Exemplo n.º 1
0
        public static string GetToken(HttpContext httpContext)
        {
            string response;

            try
            {
                // Retrieve the token with the specified scopes
                string[] scope          = _options["Scopes"].Split(' ');
                string   signedInUserID = httpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                IConfidentialClientApplication cca =
                    ConfidentialClientApplicationBuilder.Create(_options["ClientId"])
                    .WithClientSecret(_options["ClientSecret"])
                    .WithB2CAuthority("https://emsfiiot.b2clogin.com/tfp/emsfiiot.onmicrosoft.com/B2C_1_Signin/v2.0")
                    .Build();
                ITokenCache cache = new MSALStaticCache(signedInUserID, httpContext).EnablePersistence(cca.UserTokenCache);

                IEnumerable <IAccount> accounts     = cca.GetAccountsAsync().Result;
                AuthenticationResult   tokenRequest = cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync().Result;

                if (tokenRequest.AccessToken != null)
                {
                    httpContext.Response.Cookies.Append("ADB2CToken",
                                                        tokenRequest.AccessToken,
                                                        new CookieOptions
                    {
                        Expires = tokenRequest.ExpiresOn
                    });
                }

                response = tokenRequest.AccessToken;
            }
            catch (MsalUiRequiredException ex)
            {
                response = $"Session has expired. Please sign in again. {ex.Message}";
                httpContext.Response.Redirect("/Account/SignIn");
            }
            catch (Exception ex)
            {
                response = $"Error calling API: {ex.Message}";
            }

            return(response);
        }
Exemplo n.º 2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            new EMSfIIoTApiConnector(Configuration.GetSection("AzureAdB2C"));
            new BoschIoTSuiteApiConnector(Configuration.GetSection("BoschIoTSuite"));
            new GraphApiConnector(Configuration.GetSection("AzureAdB2C"));

            IdentityModelEventSource.ShowPII = true;

            services.TryAddSingleton <CommonLocalizationService>();
            services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
            .AddAzureADB2C(options =>
            {
                options.Instance              = Configuration["AzureAdB2C:Instance"];
                options.ClientId              = Configuration["AzureAdB2C:ClientId"];
                options.CallbackPath          = Configuration["AzureAdB2C:CallbackPath"];
                options.Domain                = Configuration["AzureAdB2C:Domain"];
                options.SignUpSignInPolicyId  = Configuration["AzureAdB2C:SignUpSignInPolicyId"];
                options.ResetPasswordPolicyId = Configuration["AzureAdB2C:ResetPasswordPolicyId"];
                options.EditProfilePolicyId   = Configuration["AzureAdB2C:EditProfilePolicyId"];
            })
            .AddCookie();

            services.Configure <OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
            {
                string authority = Configuration["AzureAdB2C:Instance"] + "tfp/" + Configuration["AzureAdB2C:Domain"] + "/" + Configuration["AzureAdB2C:SignUpSignInPolicyId"] + "/v2.0";

                options.ClientId         = Configuration["AzureAdB2C:ClientId"];
                options.Authority        = authority;
                options.UseTokenLifetime = true;
                options.SaveTokens       = true;
                options.CallbackPath     = new PathString("/auth");
                options.GetClaimsFromUserInfoEndpoint = true;
                options.ResponseMode = OpenIdConnectResponseMode.FormPost;
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    NameClaimType = "name",
                };

                options.Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = async ctx =>
                    {
                        // Use MSAL to swap the code for an access token
                        // Extract the code from the response notification
                        var code = ctx.ProtocolMessage.Code;

                        await GraphApiConnector.UpdateAdministrators();

                        string signedInUserID = ctx.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;

                        IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(Configuration["AzureAdB2C:ClientId"])
                                                             .WithB2CAuthority(authority)
                                                             .WithClientSecret(Configuration["AzureAdB2C:ClientSecret"])
                                                             .Build();

                        var cache = new MSALStaticCache(signedInUserID, ctx.HttpContext).EnablePersistence(cca.UserTokenCache);

                        try
                        {
                            AuthenticationResult result = await cca.AcquireTokenByAuthorizationCode(options.Scope, code).ExecuteAsync();

                            if (result.AccessToken != null)
                            {
                                ctx.HttpContext.Response.Cookies.Append("ADB2CToken",
                                                                        result.AccessToken,
                                                                        new CookieOptions
                                {
                                    Expires = result.ExpiresOn
                                });
                            }

                            ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                    },

                    OnRedirectToIdentityProvider = ctx =>
                    {
                        var defaultPolicy = Configuration["AzureAdB2C:SignUpSignInPolicyId"];

                        if (ctx.Properties.Items.TryGetValue("Policy", out var policy) && !policy.Equals(defaultPolicy))
                        {
                            ctx.ProtocolMessage.Scope         = OpenIdConnectScope.OpenIdProfile;
                            ctx.ProtocolMessage.ResponseType  = OpenIdConnectResponseType.IdToken;
                            ctx.ProtocolMessage.IssuerAddress = ctx.ProtocolMessage.IssuerAddress.ToLower().Replace(defaultPolicy.ToLower(), policy.ToLower());
                            ctx.Properties.Items.Remove(Configuration["AzureAdB2C:SignUpSignInPolicyId"]);
                        }
                        else if (!string.IsNullOrEmpty(Configuration["AzureAdB2C:Url"]))
                        {
                            ctx.ProtocolMessage.Scope       += $" offline_access {Configuration["AzureAdB2C:Scopes"]}";
                            ctx.ProtocolMessage.ResponseType = OpenIdConnectResponseType.CodeIdToken;
                        }

                        ctx.ProtocolMessage.UiLocales = ctx.HttpContext.Request.Query["culture"].ToString();

                        return(Task.FromResult(0));
                    },

                    OnRemoteFailure = ctx =>
                    {
                        ctx.HandleResponse();

                        // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page
                        // because password reset is not supported by a "sign-up or sign-in policy"
                        if (ctx.Failure is OpenIdConnectProtocolException && ctx.Failure.Message.Contains("AADB2C90118"))
                        {
                            // If the user clicked the reset password link, redirect to the reset password route
                            ctx.Response.Redirect("/Account/ResetPassword");
                        }
                        else if (ctx.Failure is OpenIdConnectProtocolException && ctx.Failure.Message.Contains("access_denied"))
                        {
                            ctx.Response.Redirect("/");
                        }
                        else
                        {
                            ctx.Response.Redirect("/Error?message=" + Uri.EscapeDataString(ctx.Failure.Message));
                        }
                        return(Task.FromResult(0));
                    },

                    OnRemoteSignOut = ctx =>
                    {
                        ctx.HttpContext.Response.Cookies.Delete("ADB2CToken");

                        return(Task.FromResult(0));
                    }
                };
            });