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(Constants.ObjectIdClaimType).Value).GetMSALCache();
                        var client = new ConfidentialClientApplication(authOptions.ClientId,
                                                                       authOptions.GetAuthority(principal.FindFirst(Constants.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_values" });

                        context.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                    catch (Exception ex)
                    {
                        context.Fail(ex);
                    }
                },
                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);
                }
            });
        }
 public TestServiceProxy(IOptions <B2CAuthenticationOptions> authOptions,
                         IOptions <B2CPolicies> policies,
                         IOptions <TestServiceOptions> serviceOptions,
                         IHttpContextAccessor httpContextAccessor,
                         IDistributedCache distributedCache)
 {
     this.authOptions         = authOptions.Value;
     this.policies            = policies.Value;
     this.serviceOptions      = serviceOptions.Value;
     this.httpContextAccessor = httpContextAccessor;
     this.distributedCache    = distributedCache;
 }