public override async Task HandleAuthorizationRequest([NotNull] HandleAuthorizationRequestContext context) { var options = (OpenIddictOptions)context.Options; // If no request_id parameter can be found in the current request, assume the OpenID Connect request // was not serialized yet and store the entire payload in the distributed cache to make it easier // to flow across requests and internal/external authentication/registration workflows. if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { // Generate a 256-bit request identifier using a crypto-secure random number generator. var bytes = new byte[256 / 8]; options.RandomNumberGenerator.GetBytes(bytes); context.Request.RequestId = Base64UrlEncoder.Encode(bytes); // Store the serialized authorization request parameters in the distributed cache. var stream = new MemoryStream(); using (var writer = new BsonDataWriter(stream)) { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); serializer.Serialize(writer, context.Request); } // 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; await options.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions { AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); // Create a new authorization request containing only the request_id parameter. var address = QueryHelpers.AddQueryString( uri: context.HttpContext.Request.Scheme + "://" + context.HttpContext.Request.Host + context.HttpContext.Request.PathBase + context.HttpContext.Request.Path, name: OpenIdConnectConstants.Parameters.RequestId, value: context.Request.RequestId); context.HttpContext.Response.Redirect(address); // Mark the response as handled // to skip the rest of the pipeline. context.HandleResponse(); return; } context.SkipHandler(); }