/* * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) * See https://github.com/openiddict/openiddict-core for more information concerning * the license and the contributors participating to this project. */ using System.Collections.Immutable; using Microsoft.AspNetCore; using Microsoft.Extensions.Logging; namespace OpenIddict.Server.AspNetCore; public static partial class OpenIddictServerAspNetCoreHandlers { public static class Device { public static ImmutableArray DefaultHandlers { get; } = [ /* * Device request extraction: */ ExtractPostRequest.Descriptor, ValidateClientAuthenticationMethod.Descriptor, ExtractClientCertificate.Descriptor, ExtractBasicAuthenticationCredentials.Descriptor, /* * Device response processing: */ AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, AttachWwwAuthenticateHeader.Descriptor, ProcessJsonResponse.Descriptor, /* * Verification request extraction: */ ExtractGetOrPostRequest.Descriptor, /* * Verification request handling: */ EnablePassthroughMode.Descriptor, /* * Verification response processing: */ AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, ProcessHostRedirectionResponse.Descriptor, ProcessPassthroughErrorResponse.Descriptor, ProcessStatusCodePagesErrorResponse.Descriptor, ProcessLocalErrorResponse.Descriptor, ProcessEmptyResponse.Descriptor ]; } /// /// Contains the logic responsible for processing verification responses that should trigger a host redirection. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. /// public sealed class ProcessHostRedirectionResponse : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. /// public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() .SetOrder(ProcessPassthroughErrorResponse.Descriptor.Order - 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); /// public ValueTask HandleAsync(ApplyEndUserVerificationResponseContext context) { ArgumentNullException.ThrowIfNull(context); // This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved, // this may indicate that the request was incorrectly processed by another server stack. var response = context.Transaction.GetHttpRequest()?.HttpContext.Response ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); // Note: this handler only redirects the user agent to the URI specified in the // properties when there's no error or if the error is an access_denied error. if (!string.IsNullOrEmpty(context.Response.Error) && !string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal)) { return ValueTask.CompletedTask; } var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) { response.Redirect(properties.RedirectUri); context.Logger.LogInformation(6144, SR.GetResourceString(SR.ID6144)); context.HandleRequest(); } return ValueTask.CompletedTask; } } }