/// <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()); } }