Exemplo n.º 1
0
                /// <summary>
                /// Processes the event.
                /// </summary>
                /// <param name="context">The context associated with the event to process.</param>
                /// <returns>
                /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
                /// </returns>
                public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
                {
                    if (context == null)
                    {
                        throw new ArgumentNullException(nameof(context));
                    }

                    // If a request_id parameter can be found in the authorization request,
                    // restore the complete authorization request from the distributed cache.

                    if (string.IsNullOrEmpty(context.Request.RequestId))
                    {
                        return;
                    }

                    // Note: the cache key is always prefixed with a specific marker
                    // to avoid collisions with the other types of cached payloads.
                    var payload = await _cache.GetAsync(Cache.AuthorizationRequest + context.Request.RequestId);

                    if (payload == null)
                    {
                        context.Logger.LogError("The authorization request was rejected because an unknown " +
                                                "or invalid request_id parameter was specified.");

                        context.Reject(
                            error: Errors.InvalidRequest,
                            description: "The specified 'request_id' parameter is invalid.");

                        return;
                    }

                    // Restore the authorization request parameters from the serialized payload.
                    using var reader = new BsonDataReader(new MemoryStream(payload));
                    foreach (var parameter in JObject.Load(reader))
                    {
                        // Avoid overriding the current request parameters.
                        if (context.Request.HasParameter(parameter.Key))
                        {
                            continue;
                        }

                        context.Request.SetParameter(parameter.Key, parameter.Value);
                    }
                }
        public override Task ExtractAuthorizationRequest(ExtractAuthorizationRequestContext context)
        {
            // If a request_id parameter can be found in the authorization request,
            // restore the complete authorization request stored in the user session.
            if (!string.IsNullOrEmpty(context.Request.GetRequestId()))
            {
                var payload = context.HttpContext.Session.Get("authorization-request:" + context.Request.GetRequestId());
                if (payload == null)
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidRequest,
                        description: "Invalid request: timeout expired.");

                    return(Task.FromResult(0));
                }

                // Restore the authorization request parameters.
                context.Request.Import(payload);
            }

            return(Task.FromResult(0));
        }
                /// <inheritdoc/>
                public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
                {
                    if (context is null)
                    {
                        throw new ArgumentNullException(nameof(context));
                    }

                    Debug.Assert(context.Request is not null, SR.GetResourceString(SR.ID4008));

                    // If a request_id parameter can be found in the authorization request,
                    // restore the complete authorization request from the distributed cache.

                    if (string.IsNullOrEmpty(context.Request.RequestId))
                    {
                        return;
                    }

                    // Note: the cache key is always prefixed with a specific marker
                    // to avoid collisions with the other types of cached payloads.
                    var token = await _cache.GetStringAsync(Cache.AuthorizationRequest + context.Request.RequestId);

                    if (token is null || !context.Options.JsonWebTokenHandler.CanReadToken(token))
                    {
                        context.Logger.LogInformation(SR.GetResourceString(SR.ID6146), Parameters.RequestId);

                        context.Reject(
                            error: Errors.InvalidRequest,
                            description: SR.FormatID2052(Parameters.RequestId),
                            uri: SR.FormatID8000(SR.ID2052));

                        return;
                    }

                    var parameters = context.Options.TokenValidationParameters.Clone();

                    parameters.ValidIssuer ??= context.Issuer?.AbsoluteUri;
                    parameters.ValidAudience = context.Issuer?.AbsoluteUri;
                    parameters.ValidTypes    = new[] { JsonWebTokenTypes.Private.AuthorizationRequest };

                    var result = context.Options.JsonWebTokenHandler.ValidateToken(token, parameters);

                    if (!result.IsValid)
                    {
                        context.Logger.LogInformation(SR.GetResourceString(SR.ID6146), Parameters.RequestId);

                        context.Reject(
                            error: Errors.InvalidRequest,
                            description: SR.FormatID2052(Parameters.RequestId),
                            uri: SR.FormatID8000(SR.ID2052));

                        return;
                    }

                    using var document = JsonDocument.Parse(
                              Base64UrlEncoder.Decode(((JsonWebToken)result.SecurityToken).InnerToken.EncodedPayload));
                    if (document.RootElement.ValueKind != JsonValueKind.Object)
                    {
                        throw new InvalidOperationException(SR.GetResourceString(SR.ID0117));
                    }

                    // Restore the authorization request parameters from the serialized payload.
                    foreach (var parameter in document.RootElement.EnumerateObject())
                    {
                        // Avoid overriding the current request parameters.
                        if (context.Request.HasParameter(parameter.Name))
                        {
                            continue;
                        }

                        context.Request.SetParameter(parameter.Name, parameter.Value.Clone());
                    }
                }
        public override async Task ExtractAuthorizationRequest([NotNull] ExtractAuthorizationRequestContext context)
        {
            var services = context.HttpContext.RequestServices.GetRequiredService <OpenIddictServices <TApplication, TAuthorization, TScope, TToken> >();

            // Reject requests using the unsupported request parameter.
            if (!string.IsNullOrEmpty(context.Request.Request))
            {
                services.Logger.LogError("The authorization request was rejected because it contained " +
                                         "an unsupported parameter: {Parameter}.", "request");

                context.Reject(
                    error: OpenIdConnectConstants.Errors.RequestNotSupported,
                    description: "The request parameter is not supported.");

                return;
            }

            // Reject requests using the unsupported request_uri parameter.
            if (!string.IsNullOrEmpty(context.Request.RequestUri))
            {
                services.Logger.LogError("The authorization request was rejected because it contained " +
                                         "an unsupported parameter: {Parameter}.", "request_uri");

                context.Reject(
                    error: OpenIdConnectConstants.Errors.RequestUriNotSupported,
                    description: "The request_uri parameter is not supported.");

                return;
            }

            // If a request_id parameter can be found in the authorization request,
            // restore the complete authorization request from the distributed cache.
            if (!string.IsNullOrEmpty(context.Request.RequestId))
            {
                // Return an error if request caching support was not enabled.
                if (!services.Options.EnableRequestCaching)
                {
                    services.Logger.LogError("The authorization request was rejected because " +
                                             "request caching support was not enabled.");

                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidRequest,
                        description: "The request_id parameter is not supported.");

                    return;
                }

                // Note: the cache key is always prefixed with a specific marker
                // to avoid collisions with the other types of cached requests.
                var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId;

                var payload = await services.Options.Cache.GetAsync(key);

                if (payload == null)
                {
                    services.Logger.LogError("The authorization request was rejected because an unknown " +
                                             "or invalid request_id parameter was specified.");

                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidRequest,
                        description: "Invalid request: timeout expired.");

                    return;
                }

                // Restore the authorization request parameters from the serialized payload.
                using (var reader = new BsonReader(new MemoryStream(payload))) {
                    foreach (var parameter in JObject.Load(reader))
                    {
                        // Avoid overriding the current request parameters.
                        if (context.Request.HasParameter(parameter.Key))
                        {
                            continue;
                        }

                        context.Request.SetParameter(parameter.Key, parameter.Value);
                    }
                }
            }
        }
                /// <summary>
                /// Processes the event.
                /// </summary>
                /// <param name="context">The context associated with the event to process.</param>
                /// <returns>
                /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
                /// </returns>
                public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
                {
                    if (context == null)
                    {
                        throw new ArgumentNullException(nameof(context));
                    }

                    // If a request_id parameter can be found in the authorization request,
                    // restore the complete authorization request from the distributed cache.

                    if (string.IsNullOrEmpty(context.Request.RequestId))
                    {
                        return;
                    }

                    // Note: the cache key is always prefixed with a specific marker
                    // to avoid collisions with the other types of cached payloads.
                    var token = await _cache.GetStringAsync(Cache.AuthorizationRequest + context.Request.RequestId);

                    if (token == null || !context.Options.JsonWebTokenHandler.CanReadToken(token))
                    {
                        context.Logger.LogError("The authorization request was rejected because an unknown " +
                                                "or invalid request_id parameter was specified.");

                        context.Reject(
                            error: Errors.InvalidRequest,
                            description: "The specified 'request_id' parameter is invalid.");

                        return;
                    }

                    // Restore the authorization request parameters from the serialized payload.
                    var parameters = new TokenValidationParameters
                    {
                        IssuerSigningKeys   = context.Options.SigningCredentials.Select(credentials => credentials.Key),
                        TokenDecryptionKeys = context.Options.EncryptionCredentials.Select(credentials => credentials.Key),
                        ValidateLifetime    = false,
                        ValidAudience       = context.Issuer.AbsoluteUri,
                        ValidIssuer         = context.Issuer.AbsoluteUri,
                        ValidTypes          = new[] { JsonWebTokenTypes.AuthorizationRequest }
                    };

                    var result = context.Options.JsonWebTokenHandler.ValidateToken(token, parameters);

                    if (!result.IsValid)
                    {
                        context.Logger.LogError("The authorization request was rejected because an unknown " +
                                                "or invalid request_id parameter was specified.");

                        context.Reject(
                            error: Errors.InvalidRequest,
                            description: "The specified 'request_id' parameter is invalid.");

                        return;
                    }

                    using var document = JsonDocument.Parse(
                              Base64UrlEncoder.Decode(((JsonWebToken)result.SecurityToken).InnerToken.EncodedPayload));
                    if (document.RootElement.ValueKind != JsonValueKind.Object)
                    {
                        throw new InvalidOperationException("The authorization request payload is malformed.");
                    }

                    foreach (var parameter in document.RootElement.EnumerateObject())
                    {
                        // Avoid overriding the current request parameters.
                        if (context.Request.HasParameter(parameter.Name))
                        {
                            continue;
                        }

                        context.Request.SetParameter(parameter.Name, parameter.Value.Clone());
                    }
                }
        public override async Task ExtractAuthorizationRequest([NotNull] ExtractAuthorizationRequestContext context)
        {
            var services = context.HttpContext.RequestServices.GetRequiredService <OpenIddictServices <TApplication, TAuthorization, TScope, TToken> >();

            // Reject requests using the unsupported request parameter.
            if (!string.IsNullOrEmpty(context.Request.Request))
            {
                services.Logger.LogError("The authorization request was rejected because it contained " +
                                         "an unsupported parameter: {Parameter}.", "request");

                context.Reject(
                    error: OpenIdConnectConstants.Errors.RequestNotSupported,
                    description: "The request parameter is not supported.");

                return;
            }

            // Reject requests using the unsupported request_uri parameter.
            if (!string.IsNullOrEmpty(context.Request.RequestUri))
            {
                services.Logger.LogError("The authorization request was rejected because it contained " +
                                         "an unsupported parameter: {Parameter}.", "request_uri");

                context.Reject(
                    error: OpenIdConnectConstants.Errors.RequestUriNotSupported,
                    description: "The request_uri parameter is not supported.");

                return;
            }

            // If a request_id parameter can be found in the authorization request,
            // restore the complete authorization request stored in the distributed cache.
            if (!string.IsNullOrEmpty(context.Request.RequestId))
            {
                // Note: the cache key is always prefixed with a specific marker
                // to avoid collisions with the other types of cached requests.
                var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId;

                var payload = await services.Options.Cache.GetAsync(key);

                if (payload == null)
                {
                    services.Logger.LogError("The authorization request was rejected because an unknown " +
                                             "or invalid request_id parameter was specified.");

                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidRequest,
                        description: "Invalid request: timeout expired.");

                    return;
                }

                // Restore the authorization request parameters from the serialized payload.
                using (var reader = new BsonReader(new MemoryStream(payload))) {
                    var serializer = JsonSerializer.CreateDefault();

                    // Note: JsonSerializer.Populate() automatically preserves
                    // the original request parameters resolved from the cache
                    // when parameters with the same names are specified.
                    serializer.Populate(reader, context.Request);
                }
            }
        }