From 79de4d24595fdbc70f90c6e40ffe28c347c8a9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sat, 19 Sep 2020 19:30:57 +0200 Subject: [PATCH] Fix the ProcessHostRedirectionResponse handler to be executed early enough --- ...ServerAspNetCoreHandlers.Authentication.cs | 8 +-- ...enIddictServerAspNetCoreHandlers.Device.cs | 62 ++++++++++++++++- ...nIddictServerAspNetCoreHandlers.Session.cs | 59 +++++++++++++++-- .../OpenIddictServerAspNetCoreHandlers.cs | 63 +++--------------- ...IddictServerOwinHandlers.Authentication.cs | 8 +-- .../OpenIddictServerOwinHandlers.Device.cs | 62 ++++++++++++++++- .../OpenIddictServerOwinHandlers.Session.cs | 66 +++++++++++++++++-- .../OpenIddictServerOwinHandlers.cs | 61 ++--------------- .../OpenIddictValidationAspNetCoreHandlers.cs | 10 +-- .../OpenIddictValidationOwinHandlers.cs | 10 +-- 10 files changed, 268 insertions(+), 141 deletions(-) diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs index e9973394..b9edd910 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs @@ -288,7 +288,7 @@ namespace OpenIddict.Server.AspNetCore .AddFilter() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessFormPostResponse.Descriptor.Order - 1_000) + .SetOrder(int.MinValue + 100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -333,7 +333,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessQueryResponse.Descriptor.Order - 1_000) + .SetOrder(50_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -423,7 +423,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessFragmentResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessFormPostResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -487,7 +487,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessLocalErrorResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessQueryResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs index fe150e46..5ca3cedb 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs @@ -4,9 +4,16 @@ * the license and the contributors participating to this project. */ +using System; using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Logging; +using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; +using SR = OpenIddict.Abstractions.OpenIddictResources; namespace OpenIddict.Server.AspNetCore { @@ -44,11 +51,64 @@ namespace OpenIddict.Server.AspNetCore */ AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, + ProcessHostRedirectionResponse.Descriptor, ProcessPassthroughErrorResponse.Descriptor, ProcessStatusCodePagesErrorResponse.Descriptor, ProcessLocalErrorResponse.Descriptor, - ProcessHostRedirectionResponse.Descriptor, ProcessEmptyResponse.Descriptor); } + + /// + /// Contains the logic responsible of 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 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(ApplyVerificationResponseContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(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; + if (response is null) + { + throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); + } + + // Note: this handler only redirects the user agent to the address specified + // in the AuthenticationProperties if the error is an access_denied error. + if (!string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal)) + { + return default; + } + + var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); + if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) + { + response.Redirect(properties.RedirectUri); + + context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); + context.HandleRequest(); + } + + return default; + } + } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs index 08e3ef10..d97b7a2e 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs @@ -14,6 +14,7 @@ using System.Security.Cryptography; using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; @@ -52,11 +53,11 @@ namespace OpenIddict.Server.AspNetCore RemoveCachedRequest.Descriptor, AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, - ProcessRedirectionResponse.Descriptor, ProcessPassthroughErrorResponse.Descriptor, ProcessStatusCodePagesErrorResponse.Descriptor, ProcessLocalErrorResponse.Descriptor, - ProcessHostRedirectionResponse.Descriptor, + ProcessQueryResponse.Descriptor, + ProcessHostRedirectionResponse.Descriptor, ProcessEmptyResponse.Descriptor); /// @@ -285,7 +286,7 @@ namespace OpenIddict.Server.AspNetCore .AddFilter() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessRedirectionResponse.Descriptor.Order - 1_000) + .SetOrder(int.MinValue + 100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -316,7 +317,7 @@ namespace OpenIddict.Server.AspNetCore /// Contains the logic responsible of processing logout responses. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. /// - public class ProcessRedirectionResponse : IOpenIddictServerHandler + public class ProcessQueryResponse : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -324,8 +325,8 @@ namespace OpenIddict.Server.AspNetCore public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .UseSingletonHandler() - .SetOrder(ProcessStatusCodePagesErrorResponse.Descriptor.Order - 1_000) + .UseSingletonHandler() + .SetOrder(ProcessLocalErrorResponse.Descriptor.Order + 250) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -374,6 +375,52 @@ namespace OpenIddict.Server.AspNetCore return default; } } + + /// + /// Contains the logic responsible of processing logout 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 class ProcessHostRedirectionResponse : IOpenIddictServerHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictServerHandlerDescriptor Descriptor { get; } + = OpenIddictServerHandlerDescriptor.CreateBuilder() + .AddFilter() + .UseSingletonHandler() + .SetOrder(ProcessQueryResponse.Descriptor.Order + 250) + .SetType(OpenIddictServerHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(ApplyLogoutResponseContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(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; + if (response is null) + { + throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); + } + + var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); + if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) + { + response.Redirect(properties.RedirectUri); + + context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); + context.HandleRequest(); + } + + return default; + } + } } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs index 54d48db7..985b5a50 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs @@ -783,7 +783,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachCacheControlHeader.Descriptor.Order - 1_000) + .SetOrder(100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -843,7 +843,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order - 1_000) + .SetOrder(AttachHttpResponseCode.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -890,7 +890,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order - 1_000) + .SetOrder(AttachCacheControlHeader.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1004,7 +1004,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessJsonResponse.Descriptor.Order - 1_000) + .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1050,7 +1050,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessPassthroughErrorResponse>.Descriptor.Order - 1_000) + .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1112,7 +1112,7 @@ namespace OpenIddict.Server.AspNetCore .AddFilter() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessStatusCodePagesErrorResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessJsonResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1160,7 +1160,7 @@ namespace OpenIddict.Server.AspNetCore .AddFilter() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessLocalErrorResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessPassthroughErrorResponse>.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1219,7 +1219,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessEmptyResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessStatusCodePagesErrorResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1282,53 +1282,6 @@ namespace OpenIddict.Server.AspNetCore } } - /// - /// Contains the logic responsible of processing empty OpenID Connect 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 class ProcessHostRedirectionResponse : IOpenIddictServerHandler - where TContext : BaseRequestContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(ProcessEmptyResponse.Descriptor.Order - 1_000) - .SetType(OpenIddictServerHandlerType.BuiltIn) - .Build(); - - /// - public ValueTask HandleAsync(TContext context) - { - if (context is null) - { - throw new ArgumentNullException(nameof(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; - if (response is null) - { - throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); - } - - var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); - if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) - { - response.Redirect(properties.RedirectUri); - - context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); - context.HandleRequest(); - } - - return default; - } - } - /// /// Contains the logic responsible of processing OpenID Connect responses that don't specify any parameter. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs index 41ee3c78..a92a63b1 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs @@ -282,7 +282,7 @@ namespace OpenIddict.Server.Owin .AddFilter() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessFormPostResponse.Descriptor.Order - 1_000) + .SetOrder(int.MinValue + 100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -327,7 +327,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessQueryResponse.Descriptor.Order - 1_000) + .SetOrder(50_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -418,7 +418,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessFragmentResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessFormPostResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -482,7 +482,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessLocalErrorResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessQueryResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs index ed1dc39f..04e634b5 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs @@ -4,9 +4,16 @@ * the license and the contributors participating to this project. */ +using System; using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Owin.Security; +using Owin; +using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; +using SR = OpenIddict.Abstractions.OpenIddictResources; namespace OpenIddict.Server.Owin { @@ -44,10 +51,63 @@ namespace OpenIddict.Server.Owin */ AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, + ProcessHostRedirectionResponse.Descriptor, ProcessPassthroughErrorResponse.Descriptor, ProcessLocalErrorResponse.Descriptor, - ProcessHostRedirectionResponse.Descriptor, ProcessEmptyResponse.Descriptor); } + + /// + /// Contains the logic responsible of 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 OWIN. + /// + public 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(ApplyVerificationResponseContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + // This handler only applies to OWIN requests. If The OWIN request cannot be resolved, + // this may indicate that the request was incorrectly processed by another server stack. + var response = context.Transaction.GetOwinRequest()?.Context.Response; + if (response is null) + { + throw new InvalidOperationException(SR.GetResourceString(SR.ID0120)); + } + + // Note: this handler only redirects the user agent to the address specified + // in the AuthenticationProperties if the error is an access_denied error. + if (!string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal)) + { + return default; + } + + var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); + if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) + { + response.Redirect(properties.RedirectUri); + + context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); + context.HandleRequest(); + } + + return default; + } + } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs index a3b52582..213c74ed 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Options; using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; using Microsoft.Owin.Infrastructure; +using Microsoft.Owin.Security; using Owin; using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.OpenIddictServerEvents; @@ -52,10 +53,10 @@ namespace OpenIddict.Server.Owin RemoveCachedRequest.Descriptor, AttachHttpResponseCode.Descriptor, AttachCacheControlHeader.Descriptor, - ProcessRedirectionResponse.Descriptor, ProcessPassthroughErrorResponse.Descriptor, ProcessLocalErrorResponse.Descriptor, - ProcessHostRedirectionResponse.Descriptor, + ProcessQueryResponse.Descriptor, + ProcessHostRedirectionResponse.Descriptor, ProcessEmptyResponse.Descriptor); /// @@ -279,7 +280,7 @@ namespace OpenIddict.Server.Owin .AddFilter() .AddFilter() .UseSingletonHandler() - .SetOrder(ProcessRedirectionResponse.Descriptor.Order - 1_000) + .SetOrder(int.MinValue + 100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -310,7 +311,7 @@ namespace OpenIddict.Server.Owin /// Contains the logic responsible of processing logout responses. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. /// - public class ProcessRedirectionResponse : IOpenIddictServerHandler + public class ProcessQueryResponse : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -318,8 +319,8 @@ namespace OpenIddict.Server.Owin public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .UseSingletonHandler() - .SetOrder(ProcessPassthroughErrorResponse>.Descriptor.Order - 1_000) + .UseSingletonHandler() + .SetOrder(ProcessLocalErrorResponse.Descriptor.Order + 250) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -368,6 +369,59 @@ namespace OpenIddict.Server.Owin return default; } } + + /// + /// Contains the logic responsible of 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 OWIN. + /// + public class ProcessHostRedirectionResponse : IOpenIddictServerHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictServerHandlerDescriptor Descriptor { get; } + = OpenIddictServerHandlerDescriptor.CreateBuilder() + .AddFilter() + .UseSingletonHandler() + .SetOrder(ProcessQueryResponse.Descriptor.Order + 250) + .SetType(OpenIddictServerHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(ApplyVerificationResponseContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + // This handler only applies to OWIN requests. If The OWIN request cannot be resolved, + // this may indicate that the request was incorrectly processed by another server stack. + var response = context.Transaction.GetOwinRequest()?.Context.Response; + if (response is null) + { + throw new InvalidOperationException(SR.GetResourceString(SR.ID0120)); + } + + // Note: this handler only redirects the user agent to the address specified + // in the AuthenticationProperties if the error is an access_denied error. + if (!string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal)) + { + return default; + } + + var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); + if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) + { + response.Redirect(properties.RedirectUri); + + context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); + context.HandleRequest(); + } + + return default; + } + } } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs index 47bcef0b..b0ec2f95 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs @@ -720,7 +720,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachCacheControlHeader.Descriptor.Order - 1_000) + .SetOrder(100_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -780,7 +780,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order - 1_000) + .SetOrder(AttachHttpResponseCode.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -827,7 +827,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order - 1_000) + .SetOrder(AttachCacheControlHeader.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -941,7 +941,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessJsonResponse.Descriptor.Order - 1_000) + .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -987,7 +987,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessPassthroughErrorResponse>.Descriptor.Order - 1_000) + .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1049,7 +1049,7 @@ namespace OpenIddict.Server.Owin .AddFilter() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessLocalErrorResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessJsonResponse.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1099,7 +1099,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessEmptyResponse.Descriptor.Order - 1_000) + .SetOrder(ProcessPassthroughErrorResponse>.Descriptor.Order + 1_000) .SetType(OpenIddictServerHandlerType.BuiltIn) .Build(); @@ -1162,53 +1162,6 @@ namespace OpenIddict.Server.Owin } } - /// - /// Contains the logic responsible of processing empty OpenID Connect responses that should trigger a host redirection. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class ProcessHostRedirectionResponse : IOpenIddictServerHandler - where TContext : BaseRequestContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(ProcessEmptyResponse.Descriptor.Order - 1_000) - .SetType(OpenIddictServerHandlerType.BuiltIn) - .Build(); - - /// - public ValueTask HandleAsync(TContext context) - { - if (context is null) - { - throw new ArgumentNullException(nameof(context)); - } - - // This handler only applies to OWIN requests. If The OWIN request cannot be resolved, - // this may indicate that the request was incorrectly processed by another server stack. - var response = context.Transaction.GetOwinRequest()?.Context.Response; - if (response is null) - { - throw new InvalidOperationException(SR.GetResourceString(SR.ID0120)); - } - - var properties = context.Transaction.GetProperty(typeof(AuthenticationProperties).FullName!); - if (properties is not null && !string.IsNullOrEmpty(properties.RedirectUri)) - { - response.Redirect(properties.RedirectUri); - - context.Logger.LogInformation(SR.GetResourceString(SR.ID6144)); - context.HandleRequest(); - } - - return default; - } - } - /// /// Contains the logic responsible of processing OpenID Connect responses that don't specify any parameter. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs index c971e7a8..1fed4b76 100644 --- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs +++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs @@ -346,7 +346,7 @@ namespace OpenIddict.Validation.AspNetCore = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachCacheControlHeader.Descriptor.Order - 1_000) + .SetOrder(100_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -398,7 +398,7 @@ namespace OpenIddict.Validation.AspNetCore = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order - 1_000) + .SetOrder(AttachHttpResponseCode.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -445,7 +445,7 @@ namespace OpenIddict.Validation.AspNetCore = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order - 1_000) + .SetOrder(AttachCacheControlHeader.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -550,7 +550,7 @@ namespace OpenIddict.Validation.AspNetCore = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessJsonResponse.Descriptor.Order - 1_000) + .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -596,7 +596,7 @@ namespace OpenIddict.Validation.AspNetCore = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(int.MaxValue - 100_000) + .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs index aed9d25d..ae91c96c 100644 --- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs +++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs @@ -348,7 +348,7 @@ namespace OpenIddict.Validation.Owin = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachCacheControlHeader.Descriptor.Order - 1_000) + .SetOrder(100_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -400,7 +400,7 @@ namespace OpenIddict.Validation.Owin = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order - 1_000) + .SetOrder(AttachHttpResponseCode.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -447,7 +447,7 @@ namespace OpenIddict.Validation.Owin = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order - 1_000) + .SetOrder(AttachCacheControlHeader.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -557,7 +557,7 @@ namespace OpenIddict.Validation.Owin = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ProcessJsonResponse.Descriptor.Order - 1_000) + .SetOrder(AttachWwwAuthenticateHeader.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build(); @@ -603,7 +603,7 @@ namespace OpenIddict.Validation.Owin = OpenIddictValidationHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(int.MaxValue - 100_000) + .SetOrder(ProcessChallengeErrorResponse.Descriptor.Order + 1_000) .SetType(OpenIddictValidationHandlerType.BuiltIn) .Build();