public async Task <Task> OnRemoteFailure(RemoteFailureContext context)
            {
                context.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 (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
                {
                    // If the user clicked the reset password link, redirect to the reset password route
                    var authProp = new AuthenticationProperties()
                    {
                        RedirectUri = "/"
                    };
                    authProp.Items[AzureAdB2COptions.PolicyAuthenticationProperty] = azureOptions.ResetPasswordPolicyId;

                    await context.HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, authProp);
                }
                else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
                {
                    context.Response.Redirect("/");
                }
                else
                {
                    context.Response.Redirect("/Home/Error");
                }

                return(Task.CompletedTask);
            }
        /// <summary>Handles the remote failure.</summary>
        /// <param name="context">The context.</param>
        /// <returns>A task.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="context"/> is <see langword="null"/>.</exception>
        public static Task HandleRemoteFailure(this RemoteFailureContext context)
        {
            if (context == default)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Properties.Items.ContainsKey(Referer))
            {
                context.Response.Redirect($"{context.Properties.Items[Referer]}");
            }

            context.HandleResponse();
            return(CompletedTask);
        }
 public Task OnRemoteFailure(RemoteFailureContext context)
 {
     context.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 (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
     {
         // If the user clicked the reset password link, redirect to the reset password route
         context.Response.Redirect("/Account/ResetPassword");
     }
     else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
     {
         context.Response.Redirect("/");
     }
     else
     {
         context.Response.Redirect("/Home/Error");
     }
     return(Task.CompletedTask);
 }
        public virtual async Task <bool> HandleRequestAsync()
        {
            if (!await ShouldHandleRequestAsync())
            {
                return(false);
            }

            AuthenticationTicket     ticket     = null;
            Exception                exception  = null;
            AuthenticationProperties properties = null;

            try
            {
                var authResult = await HandleRemoteAuthenticateAsync();

                if (authResult == null)
                {
                    exception = new InvalidOperationException("Invalid return state, unable to redirect.");
                }
                else if (authResult.Handled)
                {
                    return(true);
                }
                else if (authResult.Skipped || authResult.None)
                {
                    return(false);
                }
                else if (!authResult.Succeeded)
                {
                    exception  = authResult.Failure ?? new InvalidOperationException("Invalid return state, unable to redirect.");
                    properties = authResult.Properties;
                }

                ticket = authResult?.Ticket;
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (exception != null)
            {
                Logger.RemoteAuthenticationError(exception.Message);
                var errorContext = new RemoteFailureContext(Context, Scheme, Options, exception)
                {
                    Properties = properties
                };
                await Events.RemoteFailure(errorContext);

                if (errorContext.Result != null)
                {
                    if (errorContext.Result.Handled)
                    {
                        return(true);
                    }
                    else if (errorContext.Result.Skipped)
                    {
                        return(false);
                    }
                    else if (errorContext.Result.Failure != null)
                    {
                        throw new Exception("An error was returned from the RemoteFailure event.", errorContext.Result.Failure);
                    }
                }

                if (errorContext.Failure != null)
                {
                    throw new Exception("An error was encountered while handling the remote login.", errorContext.Failure);
                }
            }

            // We have a ticket if we get here
            var ticketContext = new TicketReceivedContext(Context, Scheme, Options, ticket)
            {
                ReturnUri = ticket.Properties.RedirectUri
            };

            ticket.Properties.RedirectUri = null;

            // Mark which provider produced this identity so we can cross-check later in HandleAuthenticateAsync
            ticketContext.Properties.Items[AuthSchemeKey] = Scheme.Name;

            await Events.TicketReceived(ticketContext);

            if (ticketContext.Result != null)
            {
                if (ticketContext.Result.Handled)
                {
                    Logger.SignInHandled();
                    return(true);
                }
                else if (ticketContext.Result.Skipped)
                {
                    Logger.SignInSkipped();
                    return(false);
                }
            }

            await Context.SignInAsync(SignInScheme, ticketContext.Principal, ticketContext.Properties);

            // Default redirect path is the base path
            if (string.IsNullOrEmpty(ticketContext.ReturnUri))
            {
                ticketContext.ReturnUri = "/";
            }

            Response.Redirect(ticketContext.ReturnUri);
            return(true);
        }
 /// <summary>
 /// Invoked when there is a remote failure.
 /// </summary>
 public virtual Task RemoteFailure(RemoteFailureContext context) => OnRemoteFailure(context);