Esempio n. 1
0
        private async Task <bool> HandleUnauthorizedAsync(AuthenticationProperties properties)
        {
            // Extract the OpenID Connect request from the ASP.NET Core context.
            // If it cannot be found or doesn't correspond to an authorization
            // or a token request, throw an InvalidOperationException.
            var request = Context.GetOpenIdConnectRequest();

            if (request == null || (!request.IsAuthorizationRequest() && !request.IsTokenRequest()))
            {
                throw new InvalidOperationException("An authorization or token response cannot be returned from this endpoint.");
            }

            // Note: if a response was already generated, throw an exception.
            var response = Context.GetOpenIdConnectResponse();

            if (response != null || Response.HasStarted)
            {
                throw new InvalidOperationException("A response has already been sent.");
            }

            // Prepare a new OpenID Connect response.
            response = new OpenIdConnectResponse
            {
                Error            = properties.GetProperty(OpenIdConnectConstants.Properties.Error),
                ErrorDescription = properties.GetProperty(OpenIdConnectConstants.Properties.ErrorDescription),
                ErrorUri         = properties.GetProperty(OpenIdConnectConstants.Properties.ErrorUri)
            };

            // Remove the error/error_description/error_uri properties from the ticket.
            properties.RemoveProperty(OpenIdConnectConstants.Properties.Error)
            .RemoveProperty(OpenIdConnectConstants.Properties.ErrorDescription)
            .RemoveProperty(OpenIdConnectConstants.Properties.ErrorUri);

            if (string.IsNullOrEmpty(response.Error))
            {
                response.Error = request.IsAuthorizationRequest() ?
                                 OpenIdConnectConstants.Errors.AccessDenied :
                                 OpenIdConnectConstants.Errors.InvalidGrant;
            }

            if (string.IsNullOrEmpty(response.ErrorDescription))
            {
                response.ErrorDescription = request.IsAuthorizationRequest() ?
                                            "The authorization was denied by the resource owner." :
                                            "The token request was rejected by the authorization server.";
            }

            Logger.LogTrace("A challenge operation was triggered: {Properties}.", properties.Items);

            var notification = new ProcessChallengeResponseContext(Context, Scheme, Options, properties, request, response);
            await Provider.ProcessChallengeResponse(notification);

            if (notification.Result != null)
            {
                if (notification.Result.Handled)
                {
                    Logger.LogDebug("The challenge response was handled in user code.");

                    return(true);
                }

                else if (notification.Result.Skipped)
                {
                    Logger.LogDebug("The default challenge handling was skipped from user code.");

                    return(false);
                }
            }

            else if (notification.IsRejected)
            {
                Logger.LogError("The request was rejected with the following error: {Error} ; {Description}",
                                /* Error: */ notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
                                /* Description: */ notification.ErrorDescription);

                if (request.IsAuthorizationRequest())
                {
                    return(await SendAuthorizationResponseAsync(new OpenIdConnectResponse
                    {
                        Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
                        ErrorDescription = notification.ErrorDescription,
                        ErrorUri = notification.ErrorUri
                    }));
                }

                return(await SendTokenResponseAsync(new OpenIdConnectResponse
                {
                    Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
                    ErrorDescription = notification.ErrorDescription,
                    ErrorUri = notification.ErrorUri
                }));
            }

            // Flow the changes made to the properties.
            properties = notification.Properties;

            // Create a new ticket containing an empty identity and
            // the authentication properties extracted from the context.
            var ticket = new AuthenticationTicket(
                new ClaimsPrincipal(new ClaimsIdentity()),
                properties, Scheme.Name);

            if (request.IsAuthorizationRequest())
            {
                return(await SendAuthorizationResponseAsync(response, ticket));
            }

            return(await SendTokenResponseAsync(response, ticket));
        }
 /// <summary>
 /// Represents an event called when processing a challenge response.
 /// </summary>
 /// <param name="context">The context instance associated with this event.</param>
 /// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
 public virtual Task ProcessChallengeResponse(ProcessChallengeResponseContext context)
 => OnProcessChallengeResponse(context);