private static IOpenIdConnectEvents CreateOpenIdConnectEventHandlers(B2CAuthenticationOptions authOptions,
                                                                             B2CPolicies policies, IDistributedCache distributedCache)
        {
            return(new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = context => SetIssuerAddressAsync(context, policies.SignInOrSignUpPolicy),
                OnRedirectToIdentityProviderForSignOut = context => SetIssuerAddressForSignOutAsync(context, policies.SignInOrSignUpPolicy),
                OnAuthorizationCodeReceived = async context =>
                {
                    try
                    {
                        var userId = context.Ticket.Principal.FindFirst(B2CAuthConstants.ObjectId).Value;

                        var credential = new ClientCredential(authOptions.ClientId, authOptions.ClientSecret);
                        var authenticationContext = new AuthenticationContext(authOptions.Authority, new DistributedTokenCache(distributedCache, userId));

                        var result = await authenticationContext.AcquireTokenByAuthorizationCodeAsync(context.TokenEndpointRequest.Code,
                                                                                                      new Uri(context.TokenEndpointRequest.RedirectUri, UriKind.RelativeOrAbsolute), credential,
                                                                                                      new[] { authOptions.ClientId }, context.Ticket.Principal.FindFirst(B2CAuthConstants.AcrClaimType).Value);

                        context.HandleCodeRedemption();
                    }
                    catch
                    {
                        context.HandleResponse();
                    }
                },
                OnTokenValidated = context =>
                {
                    var claimsIdentity = (ClaimsIdentity)context.Ticket.Principal.Identity;
                    claimsIdentity.AddClaim(new Claim(BookFastClaimTypes.InteractorRole, InteractorRole.Customer.ToString()));
                    return Task.FromResult(0);
                },
                OnAuthenticationFailed = context =>
                {
                    context.SkipToNextMiddleware();
                    return Task.FromResult(0);
                },
                OnMessageReceived = context =>
                {
                    if (!string.IsNullOrEmpty(context.ProtocolMessage.Error) &&
                        !string.IsNullOrEmpty(context.ProtocolMessage.ErrorDescription) &&
                        context.ProtocolMessage.ErrorDescription.StartsWith("AADB2C90091") &&
                        context.Properties.Items[B2CAuthConstants.B2CPolicy] == policies.EditProfilePolicy)
                    {
                        context.Ticket = new Microsoft.AspNetCore.Authentication.AuthenticationTicket(context.HttpContext.User, context.Properties, B2CAuthConstants.OpenIdConnectB2CAuthenticationScheme);
                        context.HandleResponse();
                    }

                    return Task.FromResult(0);
                }
            });
        }
示例#2
0
        private static OpenIdConnectEvents CreateOpenIdConnectEventHandlers(B2CAuthenticationOptions authOptions,
                                                                            B2CPolicies policies, IDistributedCache distributedCache)
        {
            return(new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = context => SetIssuerAddressAsync(context, policies.SignInOrSignUpPolicy),
                OnRedirectToIdentityProviderForSignOut = context => SetIssuerAddressForSignOutAsync(context, policies.SignInOrSignUpPolicy),
                OnAuthorizationCodeReceived = async context =>
                {
                    try
                    {
                        var principal = context.Principal;

                        var userTokenCache = new DistributedTokenCache(distributedCache, principal.FindFirst(B2CAuthConstants.ObjectIdClaimType).Value).GetMSALCache();
                        var client = new ConfidentialClientApplication(authOptions.ClientId,
                                                                       authOptions.GetAuthority(principal.FindFirst(B2CAuthConstants.AcrClaimType).Value),
                                                                       "https://app", // it's not really needed
                                                                       new ClientCredential(authOptions.ClientSecret),
                                                                       userTokenCache,
                                                                       null);

                        var result = await client.AcquireTokenByAuthorizationCodeAsync(context.TokenEndpointRequest.Code,
                                                                                       new[] { $"{authOptions.ApiIdentifier}/read_booking", $"{authOptions.ApiIdentifier}/update_booking" });

                        context.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                    catch (Exception ex)
                    {
                        context.Fail(ex);
                    }
                },
                OnTokenValidated = context =>
                {
                    var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;
                    claimsIdentity.AddClaim(new Claim(BookFastClaimTypes.InteractorRole, InteractorRole.Customer.ToString()));
                    return Task.FromResult(0);
                },
                OnAuthenticationFailed = context =>
                {
                    context.Fail(context.Exception);
                    return Task.FromResult(0);
                },
                OnMessageReceived = context =>
                {
                    if (!string.IsNullOrEmpty(context.ProtocolMessage.Error) &&
                        !string.IsNullOrEmpty(context.ProtocolMessage.ErrorDescription))
                    {
                        if (context.ProtocolMessage.ErrorDescription.StartsWith("AADB2C90091")) // cancel profile editing
                        {
                            context.HandleResponse();
                            context.Response.Redirect("/");
                        }
                        else if (context.ProtocolMessage.ErrorDescription.StartsWith("AADB2C90118")) // forgot password
                        {
                            context.HandleResponse();
                            context.Response.Redirect("/Account/ResetPassword");
                        }
                    }

                    return Task.FromResult(0);
                }
            });
        }
示例#3
0
        public static AuthenticationBuilder AddOpenIdConnectB2CAuthentication(this AuthenticationBuilder authenticationBuilder,
                                                                              B2CAuthenticationOptions authOptions, B2CPolicies b2cPolicies, IDistributedCache distributedCache)
        {
            authenticationBuilder.AddOpenIdConnect(B2CAuthConstants.OpenIdConnectB2CAuthenticationScheme, options =>
            {
                options.CallbackPath = new PathString(B2CAuthConstants.B2CCallbackPath);

                options.Authority            = authOptions.Authority;
                options.ClientId             = authOptions.ClientId;
                options.ClientSecret         = authOptions.ClientSecret;
                options.SignedOutRedirectUri = authOptions.PostLogoutRedirectUri;

                options.ConfigurationManager = new PolicyConfigurationManager(authOptions.Authority,
                                                                              new[] { b2cPolicies.SignInOrSignUpPolicy, b2cPolicies.EditProfilePolicy, b2cPolicies.ResetPasswordPolicy });

                options.Events = CreateOpenIdConnectEventHandlers(authOptions, b2cPolicies, distributedCache);

                options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name"
                };

                // it will fall back on using DefaultSignInScheme if not set
                //options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                options.Scope.Add("offline_access");
                options.Scope.Add($"{authOptions.ApiIdentifier}/read_booking");
                options.Scope.Add($"{authOptions.ApiIdentifier}/update_booking");
            });

            return(authenticationBuilder);
        }
        public static void UseOpenIdConnectB2CAuthentication(this IApplicationBuilder app,
                                                             B2CAuthenticationOptions authOptions, B2CPolicies b2cPolicies, IDistributedCache distributedCache,
                                                             bool automaticChallenge = false)
        {
            var openIdConnectOptions = new OpenIdConnectOptions
            {
                AuthenticationScheme = B2CAuthConstants.OpenIdConnectB2CAuthenticationScheme,
                AutomaticChallenge   = automaticChallenge,

                CallbackPath = new PathString(B2CAuthConstants.B2CCallbackPath),

                Authority             = authOptions.Authority,
                ClientId              = authOptions.ClientId,
                ClientSecret          = authOptions.ClientSecret,
                PostLogoutRedirectUri = authOptions.PostLogoutRedirectUri,

                ConfigurationManager = new PolicyConfigurationManager(authOptions.Authority,
                                                                      new[] { b2cPolicies.SignInOrSignUpPolicy, b2cPolicies.EditProfilePolicy }),
                Events = CreateOpenIdConnectEventHandlers(authOptions, b2cPolicies, distributedCache),

                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name"
                },

                SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
            };

            openIdConnectOptions.Scope.Add("offline_access");

            app.UseOpenIdConnectAuthentication(openIdConnectOptions);
        }