From fef92dfb27c6cf0d57e63084ed933b67771b76f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 12 Sep 2019 16:42:27 +0200 Subject: [PATCH] Promote the Issuer address to a global transaction property --- ...ServerAspNetCoreHandlers.Authentication.cs | 39 +---- ...ddictServerAspNetCoreHandlers.Discovery.cs | 70 -------- ...IddictServerAspNetCoreHandlers.Exchange.cs | 50 +----- ...tServerAspNetCoreHandlers.Introspection.cs | 69 -------- ...tServerAspNetCoreHandlers.Serialization.cs | 160 ------------------ ...nIddictServerAspNetCoreHandlers.Session.cs | 39 +---- ...IddictServerAspNetCoreHandlers.Userinfo.cs | 111 +----------- .../OpenIddictServerAspNetCoreHandlers.cs | 99 ++++++++--- ...IddictServerOwinHandlers.Authentication.cs | 38 +---- .../OpenIddictServerOwinHandlers.Discovery.cs | 70 -------- .../OpenIddictServerOwinHandlers.Exchange.cs | 41 +---- ...nIddictServerOwinHandlers.Introspection.cs | 69 -------- ...nIddictServerOwinHandlers.Serialization.cs | 160 ------------------ .../OpenIddictServerOwinHandlers.Session.cs | 39 +---- .../OpenIddictServerOwinHandlers.Userinfo.cs | 114 +------------ .../OpenIddictServerOwinHandlers.cs | 92 +++++++--- .../OpenIddictServerEvents.Discovery.cs | 5 - .../OpenIddictServerEvents.Introspection.cs | 6 - .../OpenIddictServerEvents.Serialization.cs | 5 - .../OpenIddictServerEvents.Userinfo.cs | 5 - .../OpenIddictServerEvents.cs | 9 + .../OpenIddictServerHandlers.Discovery.cs | 40 +---- .../OpenIddictServerHandlers.Introspection.cs | 3 +- .../OpenIddictServerHandlers.Serialization.cs | 12 +- .../OpenIddictServerHandlers.Userinfo.cs | 42 +---- .../OpenIddictServerProvider.cs | 1 + .../OpenIddictServerTransaction.cs | 5 + 27 files changed, 176 insertions(+), 1217 deletions(-) delete mode 100644 src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Serialization.cs delete mode 100644 src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Serialization.cs diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs index 7182e08f..a7550f6d 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs @@ -46,7 +46,7 @@ namespace OpenIddict.Server.AspNetCore /* * Authorization request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Authorization response processing: @@ -239,43 +239,6 @@ namespace OpenIddict.Server.AspNetCore } } - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleAuthorizationRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.SkipRequest(); - - return default; - } - } - /// /// Contains the logic responsible of removing cached authorization requests from the distributed cache. /// 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.AspNetCore/OpenIddictServerAspNetCoreHandlers.Discovery.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Discovery.cs index 21e719ba..6df1de8d 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Discovery.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Discovery.cs @@ -4,12 +4,7 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.AspNetCore; -using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; namespace OpenIddict.Server.AspNetCore @@ -24,11 +19,6 @@ namespace OpenIddict.Server.AspNetCore */ ExtractGetRequest.Descriptor, - /* - * Configuration request handling: - */ - InferIssuerFromHost.Descriptor, - /* * Configuration response processing: */ @@ -43,66 +33,6 @@ namespace OpenIddict.Server.AspNetCore * Cryptography response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - // Note: this handler must be invoked after AttachIssuer and before AttachEndpoints. - .UseSingletonHandler() - .SetOrder(OpenIddictServerHandlers.Discovery.AttachIssuer.Descriptor.Order + 500) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (!request.Host.HasValue) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Exchange.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Exchange.cs index 693e962f..71c5eb25 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Exchange.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Exchange.cs @@ -4,11 +4,7 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.AspNetCore; using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; @@ -28,56 +24,12 @@ namespace OpenIddict.Server.AspNetCore /* * Token request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Token response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleTokenRequestContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - context.SkipRequest(); - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Introspection.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Introspection.cs index 8135e8e0..1543f78f 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Introspection.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Introspection.cs @@ -4,12 +4,7 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.AspNetCore; -using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; namespace OpenIddict.Server.AspNetCore @@ -24,74 +19,10 @@ namespace OpenIddict.Server.AspNetCore */ ExtractGetOrPostRequest.Descriptor, - /* - * Introspection request handling: - */ - InferIssuerFromHost.Descriptor, - /* * Introspection response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(OpenIddictServerHandlers.Introspection.AttachMetadataClaims.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleIntrospectionRequestContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (!request.Host.HasValue) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer.AbsoluteUri; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Serialization.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Serialization.cs deleted file mode 100644 index 60f8a7e5..00000000 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Serialization.cs +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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; -using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.AspNetCore; -using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; -using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.OpenIddictServerHandlers.Serialization; - -namespace OpenIddict.Server.AspNetCore -{ - public static partial class OpenIddictServerAspNetCoreHandlers - { - public static class Serialization - { - public static ImmutableArray DefaultHandlers { get; } = ImmutableArray.Create( - /* - * Token serialization: - */ - InferTokenSerializationIssuerFromHost.Descriptor, - InferTokenSerializationIssuerFromHost.Descriptor, - InferTokenSerializationIssuerFromHost.Descriptor, - InferTokenSerializationIssuerFromHost.Descriptor, - - /* - * Token deserialization: - */ - InferTokenDeserializationIssuerFromHost.Descriptor, - InferTokenDeserializationIssuerFromHost.Descriptor, - InferTokenDeserializationIssuerFromHost.Descriptor, - InferTokenDeserializationIssuerFromHost.Descriptor); - } - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host for token deserialization. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferTokenSerializationIssuerFromHost : IOpenIddictServerHandler - where TContext : BaseSerializingContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(AttachIdentityTokenSerializationParameters.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] TContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (!request.Host.HasValue) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer; - } - - return default; - } - } - - /// - /// Contains the logic responsible of infering the discovery document issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferTokenDeserializationIssuerFromHost : IOpenIddictServerHandler - where TContext : BaseDeserializingContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(AttachIdentityTokenDeserializationParameters.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] TContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.TokenValidationParameters != null && context.TokenValidationParameters.ValidIssuer == null) - { - if (!request.Host.HasValue) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.TokenValidationParameters.ValidIssuer = issuer.AbsoluteUri; - } - - return default; - } - } - } -} diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs index e981defd..01da0d13 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs @@ -45,7 +45,7 @@ namespace OpenIddict.Server.AspNetCore /* * Logout request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Logout response processing: @@ -237,43 +237,6 @@ namespace OpenIddict.Server.AspNetCore } } - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleLogoutRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.SkipRequest(); - - return default; - } - } - /// /// Contains the logic responsible of removing cached logout requests from the distributed cache. /// 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.AspNetCore/OpenIddictServerAspNetCoreHandlers.Userinfo.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Userinfo.cs index ee05144e..3436cd34 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Userinfo.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Userinfo.cs @@ -4,14 +4,9 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.AspNetCore; using static OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.OpenIddictServerHandlers.Userinfo; namespace OpenIddict.Server.AspNetCore { @@ -29,116 +24,12 @@ namespace OpenIddict.Server.AspNetCore /* * Userinfo request handling: */ - EnablePassthroughMode.Descriptor, - InferIssuerFromHost.Descriptor, + EnablePassthroughMode.Descriptor, /* * Userinfo response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order - 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - context.SkipRequest(); - - return default; - } - } - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order + 500) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context) - { - if (context == 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 request = context.Transaction.GetHttpRequest(); - if (request == null) - { - throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (!request.Host.HasValue) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer.AbsoluteUri; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs index 4a0c5f67..863645c7 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs @@ -32,14 +32,13 @@ namespace OpenIddict.Server.AspNetCore * Top-level request processing: */ InferEndpointType.Descriptor, - ValidateTransportSecurityRequirement.Descriptor, - ValidateHost.Descriptor) + InferIssuerFromHost.Descriptor, + ValidateTransportSecurityRequirement.Descriptor) .AddRange(Authentication.DefaultHandlers) .AddRange(Discovery.DefaultHandlers) .AddRange(Exchange.DefaultHandlers) .AddRange(Introspection.DefaultHandlers) .AddRange(Revocation.DefaultHandlers) - .AddRange(Serialization.DefaultHandlers) .AddRange(Session.DefaultHandlers) .AddRange(Userinfo.DefaultHandlers); @@ -136,10 +135,10 @@ namespace OpenIddict.Server.AspNetCore } /// - /// Contains the logic responsible of rejecting OpenID Connect requests that don't use transport security. + /// Contains the logic responsible of infering the issuer URL from the HTTP request host and validating it. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. /// - public class ValidateTransportSecurityRequirement : IOpenIddictServerHandler + public class InferIssuerFromHost : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -147,8 +146,7 @@ namespace OpenIddict.Server.AspNetCore public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .AddFilter() - .UseSingletonHandler() + .UseSingletonHandler() .SetOrder(InferEndpointType.Descriptor.Order + 1_000) .Build(); @@ -174,31 +172,43 @@ namespace OpenIddict.Server.AspNetCore throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); } - // Don't require that the host be present if the request is not handled by OpenIddict. - if (context.EndpointType == OpenIddictServerEndpointType.Unknown) + // Don't require that the request host be present if the request is not handled + // by an OpenIddict endpoint or if an explicit issuer URL was already set. + if (context.Issuer != null || context.EndpointType == OpenIddictServerEndpointType.Unknown) { return default; } - // Reject authorization requests sent without transport security. - if (!request.IsHttps) + if (!request.Host.HasValue) { context.Reject( error: Errors.InvalidRequest, - description: "This server only accepts HTTPS requests."); + description: "The mandatory 'Host' header is missing."); return default; } + if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) || + !issuer.IsWellFormedOriginalString()) + { + context.Reject( + error: Errors.InvalidRequest, + description: "The specified 'Host' header is invalid."); + + return default; + } + + context.Issuer = issuer; + return default; } } /// - /// Contains the logic responsible of ensuring the host can be inferred from the request if none was set in the options. + /// Contains the logic responsible of rejecting OpenID Connect requests that don't use transport security. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. /// - public class ValidateHost : IOpenIddictServerHandler + public class ValidateTransportSecurityRequirement : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -206,8 +216,9 @@ namespace OpenIddict.Server.AspNetCore public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .UseSingletonHandler() - .SetOrder(ValidateTransportSecurityRequirement.Descriptor.Order + 1_000) + .AddFilter() + .UseSingletonHandler() + .SetOrder(InferEndpointType.Descriptor.Order + 1_000) .Build(); /// @@ -232,18 +243,18 @@ namespace OpenIddict.Server.AspNetCore throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved."); } - // Don't require that the request host be present if the request is not handled - // by an OpenIddict endpoint or if an explicit issuer URL was set in the options. - if (context.Options.Issuer != null || context.EndpointType == OpenIddictServerEndpointType.Unknown) + // Don't require that the host be present if the request is not handled by OpenIddict. + if (context.EndpointType == OpenIddictServerEndpointType.Unknown) { return default; } - if (!request.Host.HasValue) + // Reject authorization requests sent without transport security. + if (!request.IsHttps) { context.Reject( error: Errors.InvalidRequest, - description: "The mandatory 'Host' header is missing."); + description: "This server only accepts HTTPS requests."); return default; } @@ -265,7 +276,7 @@ namespace OpenIddict.Server.AspNetCore = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ValidateHost.Descriptor.Order + 1_000) + .SetOrder(ValidateTransportSecurityRequirement.Descriptor.Order + 1_000) .Build(); /// @@ -633,6 +644,45 @@ namespace OpenIddict.Server.AspNetCore } } + /// + /// Contains the logic responsible of enabling the pass-through mode for the received request. + /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. + /// + public class EnablePassthroughMode : IOpenIddictServerHandler + where TContext : BaseRequestContext + where TFilter : IOpenIddictServerHandlerFilter + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictServerHandlerDescriptor Descriptor { get; } + = OpenIddictServerHandlerDescriptor.CreateBuilder() + .AddFilter() + .AddFilter() + .UseSingletonHandler>() + .SetOrder(int.MaxValue - 100_000) + .Build(); + + /// + /// Processes the event. + /// + /// The context associated with the event to process. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public ValueTask HandleAsync([NotNull] TContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + context.SkipRequest(); + + return default; + } + } + /// /// Contains the logic responsible of processing OpenID Connect responses that must be returned as JSON. /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. @@ -704,8 +754,7 @@ namespace OpenIddict.Server.AspNetCore if (!string.IsNullOrEmpty(scheme)) { - var issuer = context.Options.Issuer; - if (issuer == null && !Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out issuer)) + if (context.Issuer == null) { throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); } @@ -717,7 +766,7 @@ namespace OpenIddict.Server.AspNetCore .Append(' ') .Append(Parameters.Realm) .Append("=\"") - .Append(issuer.AbsoluteUri) + .Append(context.Issuer.AbsoluteUri) .Append('"') .ToString(); } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs index 6e19c14e..34a2fd1c 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs @@ -44,7 +44,7 @@ namespace OpenIddict.Server.Owin /* * Authorization request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Authorization response processing: @@ -237,42 +237,6 @@ namespace OpenIddict.Server.Owin } } - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleAuthorizationRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.SkipRequest(); - - return default; - } - } - /// /// Contains the logic responsible of removing cached authorization requests from the distributed cache. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Discovery.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Discovery.cs index 2bc77a3e..5fc2a838 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Discovery.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Discovery.cs @@ -4,13 +4,8 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Owin; using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; namespace OpenIddict.Server.Owin { @@ -24,11 +19,6 @@ namespace OpenIddict.Server.Owin */ ExtractGetRequest.Descriptor, - /* - * Configuration request handling: - */ - InferIssuerFromHost.Descriptor, - /* * Configuration response processing: */ @@ -43,66 +33,6 @@ namespace OpenIddict.Server.Owin * Cryptography response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - // Note: this handler must be invoked after AttachIssuer and before AttachEndpoints. - .UseSingletonHandler() - .SetOrder(OpenIddictServerHandlers.Discovery.AttachIssuer.Descriptor.Order + 500) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (string.IsNullOrEmpty(request.Host.Value)) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Exchange.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Exchange.cs index 701df971..e0e59336 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Exchange.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Exchange.cs @@ -4,10 +4,7 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; @@ -27,48 +24,12 @@ namespace OpenIddict.Server.Owin /* * Token request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Token response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleTokenRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.SkipRequest(); - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Introspection.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Introspection.cs index 603b1c95..5fcb564d 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Introspection.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Introspection.cs @@ -4,13 +4,8 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Owin; using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; namespace OpenIddict.Server.Owin { @@ -24,74 +19,10 @@ namespace OpenIddict.Server.Owin */ ExtractGetOrPostRequest.Descriptor, - /* - * Introspection request handling: - */ - InferIssuerFromHost.Descriptor, - /* * Introspection response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(OpenIddictServerHandlers.Introspection.AttachMetadataClaims.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleIntrospectionRequestContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (string.IsNullOrEmpty(request.Host.Value)) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer.AbsoluteUri; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Serialization.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Serialization.cs deleted file mode 100644 index ca628f18..00000000 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Serialization.cs +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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; -using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using Owin; -using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.OpenIddictServerHandlers.Serialization; -using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; - -namespace OpenIddict.Server.Owin -{ - public static partial class OpenIddictServerOwinHandlers - { - public static class Serialization - { - public static ImmutableArray DefaultHandlers { get; } = ImmutableArray.Create( - /* - * Token serialization: - */ - InferIssuerFromHostForTokenSerialization.Descriptor, - InferIssuerFromHostForTokenSerialization.Descriptor, - InferIssuerFromHostForTokenSerialization.Descriptor, - InferIssuerFromHostForTokenSerialization.Descriptor, - - /* - * Token deserialization: - */ - InferIssuerFromHostForTokenDeserialization.Descriptor, - InferIssuerFromHostForTokenDeserialization.Descriptor, - InferIssuerFromHostForTokenDeserialization.Descriptor, - InferIssuerFromHostForTokenDeserialization.Descriptor); - } - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host for token deserialization. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferIssuerFromHostForTokenSerialization : IOpenIddictServerHandler - where TContext : BaseSerializingContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(AttachIdentityTokenSerializationParameters.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] TContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (string.IsNullOrEmpty(request.Host.Value)) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer; - } - - return default; - } - } - - /// - /// Contains the logic responsible of infering the discovery document issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core. - /// - public class InferIssuerFromHostForTokenDeserialization : IOpenIddictServerHandler - where TContext : BaseDeserializingContext - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler>() - .SetOrder(AttachIdentityTokenDeserializationParameters.Descriptor.Order + 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] TContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.TokenValidationParameters != null && context.TokenValidationParameters.ValidIssuer == null) - { - if (string.IsNullOrEmpty(request.Host.Value)) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.TokenValidationParameters.ValidIssuer = issuer.AbsoluteUri; - } - - return default; - } - } - } -} diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs index accc858b..95c53742 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs @@ -43,7 +43,7 @@ namespace OpenIddict.Server.Owin /* * Logout request handling: */ - EnablePassthroughMode.Descriptor, + EnablePassthroughMode.Descriptor, /* * Logout response processing: @@ -235,43 +235,6 @@ namespace OpenIddict.Server.Owin } } - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .AddFilter() - .UseSingletonHandler() - .SetOrder(int.MaxValue - 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleLogoutRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.SkipRequest(); - - return default; - } - } - /// /// Contains the logic responsible of removing cached logout requests from the distributed cache. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Userinfo.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Userinfo.cs index 293e7428..6c1d22a2 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Userinfo.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Userinfo.cs @@ -4,15 +4,9 @@ * the license and the contributors participating to this project. */ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using JetBrains.Annotations; -using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; using static OpenIddict.Server.OpenIddictServerEvents; -using static OpenIddict.Server.OpenIddictServerHandlers.Userinfo; -using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlers; -using Owin; +using static OpenIddict.Server.Owin.OpenIddictServerOwinHandlerFilters; namespace OpenIddict.Server.Owin { @@ -30,116 +24,12 @@ namespace OpenIddict.Server.Owin /* * Userinfo request handling: */ - EnablePassthroughMode.Descriptor, - InferIssuerFromHost.Descriptor, + EnablePassthroughMode.Descriptor, /* * Userinfo response processing: */ ProcessJsonResponse.Descriptor); - - /// - /// Contains the logic responsible of enabling the pass-through mode for the received request. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class EnablePassthroughMode : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order - 1_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - context.SkipRequest(); - - return default; - } - } - - /// - /// Contains the logic responsible of infering the issuer URL from the HTTP request host. - /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. - /// - public class InferIssuerFromHost : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .AddFilter() - .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order + 500) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context) - { - if (context == 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 request = context.Transaction.GetOwinRequest(); - if (request == null) - { - throw new InvalidOperationException("The OWIN request cannot be resolved."); - } - - // If the issuer was not populated by another handler (e.g from the server options), - // try to infer it from the request scheme/host/path base (which requires HTTP/1.1). - if (context.Issuer == null) - { - if (string.IsNullOrEmpty(request.Host.Value)) - { - throw new InvalidOperationException("No host was attached to the HTTP request."); - } - - if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer)) - { - throw new InvalidOperationException("The issuer address cannot be inferred from the current request."); - } - - context.Issuer = issuer.AbsoluteUri; - } - - return default; - } - } } } } diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs index 21f44a74..0e9ebb3a 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs @@ -31,14 +31,13 @@ namespace OpenIddict.Server.Owin * Top-level request processing: */ InferEndpointType.Descriptor, - ValidateTransportSecurityRequirement.Descriptor, - ValidateHost.Descriptor) + InferIssuerFromHost.Descriptor, + ValidateTransportSecurityRequirement.Descriptor) .AddRange(Authentication.DefaultHandlers) .AddRange(Discovery.DefaultHandlers) .AddRange(Exchange.DefaultHandlers) .AddRange(Introspection.DefaultHandlers) .AddRange(Revocation.DefaultHandlers) - .AddRange(Serialization.DefaultHandlers) .AddRange(Session.DefaultHandlers) .AddRange(Userinfo.DefaultHandlers); @@ -137,10 +136,10 @@ namespace OpenIddict.Server.Owin } /// - /// Contains the logic responsible of rejecting OpenID Connect requests that don't use transport security. + /// Contains the logic responsible of infering the issuer URL from the HTTP request host and validating it. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. /// - public class ValidateTransportSecurityRequirement : IOpenIddictServerHandler + public class InferIssuerFromHost : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -148,8 +147,7 @@ namespace OpenIddict.Server.Owin public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .AddFilter() - .UseSingletonHandler() + .UseSingletonHandler() .SetOrder(InferEndpointType.Descriptor.Order + 1_000) .Build(); @@ -175,18 +173,28 @@ namespace OpenIddict.Server.Owin throw new InvalidOperationException("The OWIN request cannot be resolved."); } - // Don't require that the host be present if the request is not handled by OpenIddict. - if (context.EndpointType == OpenIddictServerEndpointType.Unknown) + // Don't require that the request host be present if the request is not handled + // by an OpenIddict endpoint or if an explicit issuer URL was already set. + if (context.Issuer != null || context.EndpointType == OpenIddictServerEndpointType.Unknown) { return default; } - // Reject authorization requests sent without transport security. - if (!request.IsSecure) + if (string.IsNullOrEmpty(request.Host.Value)) { context.Reject( error: Errors.InvalidRequest, - description: "This server only accepts HTTPS requests."); + description: "The mandatory 'Host' header is missing."); + + return default; + } + + if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) || + !issuer.IsWellFormedOriginalString()) + { + context.Reject( + error: Errors.InvalidRequest, + description: "The specified 'Host' header is invalid."); return default; } @@ -196,10 +204,10 @@ namespace OpenIddict.Server.Owin } /// - /// Contains the logic responsible of ensuring the host can be inferred from the request if none was set in the options. + /// Contains the logic responsible of rejecting OpenID Connect requests that don't use transport security. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. /// - public class ValidateHost : IOpenIddictServerHandler + public class ValidateTransportSecurityRequirement : IOpenIddictServerHandler { /// /// Gets the default descriptor definition assigned to this handler. @@ -207,8 +215,9 @@ namespace OpenIddict.Server.Owin public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() - .UseSingletonHandler() - .SetOrder(ValidateTransportSecurityRequirement.Descriptor.Order + 1_000) + .AddFilter() + .UseSingletonHandler() + .SetOrder(InferEndpointType.Descriptor.Order + 1_000) .Build(); /// @@ -233,18 +242,18 @@ namespace OpenIddict.Server.Owin throw new InvalidOperationException("The OWIN request cannot be resolved."); } - // Don't require that the request host be present if the request is not handled - // by an OpenIddict endpoint or if an explicit issuer URL was set in the options. - if (context.Options.Issuer != null || context.EndpointType == OpenIddictServerEndpointType.Unknown) + // Don't require that the host be present if the request is not handled by OpenIddict. + if (context.EndpointType == OpenIddictServerEndpointType.Unknown) { return default; } - if (string.IsNullOrEmpty(request.Host.Value)) + // Reject authorization requests sent without transport security. + if (!request.IsSecure) { context.Reject( error: Errors.InvalidRequest, - description: "The mandatory 'Host' header is missing."); + description: "This server only accepts HTTPS requests."); return default; } @@ -266,7 +275,7 @@ namespace OpenIddict.Server.Owin = OpenIddictServerHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler>() - .SetOrder(ValidateHost.Descriptor.Order + 1_000) + .SetOrder(ValidateTransportSecurityRequirement.Descriptor.Order + 1_000) .Build(); /// @@ -634,6 +643,45 @@ namespace OpenIddict.Server.Owin } } + /// + /// Contains the logic responsible of enabling the pass-through mode for the received request. + /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. + /// + public class EnablePassthroughMode : IOpenIddictServerHandler + where TContext : BaseRequestContext + where TFilter : IOpenIddictServerHandlerFilter + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictServerHandlerDescriptor Descriptor { get; } + = OpenIddictServerHandlerDescriptor.CreateBuilder() + .AddFilter() + .AddFilter() + .UseSingletonHandler>() + .SetOrder(int.MaxValue - 100_000) + .Build(); + + /// + /// Processes the event. + /// + /// The context associated with the event to process. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public ValueTask HandleAsync([NotNull] TContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + context.SkipRequest(); + + return default; + } + } + /// /// Contains the logic responsible of processing OpenID Connect responses that must be returned as JSON. /// Note: this handler is not used when the OpenID Connect request is not initially handled by OWIN. diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs index fee0e9ec..f3474f09 100644 --- a/src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs +++ b/src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs @@ -99,11 +99,6 @@ namespace OpenIddict.Server /// public Uri UserinfoEndpoint { get; set; } - /// - /// Gets or sets the issuer address. - /// - public Uri Issuer { get; set; } - /// /// Gets the list of claims supported by the authorization server. /// diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs index fd6d9d25..bd40fdcd 100644 --- a/src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs +++ b/src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs @@ -105,12 +105,6 @@ namespace OpenIddict.Server /// public DateTimeOffset? IssuedAt { get; set; } - /// - /// Gets or sets the "iss" claim - /// returned to the caller, if applicable. - /// - public string Issuer { get; set; } - /// /// Gets or sets the "nbf" claim /// returned to the caller, if applicable. diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Serialization.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Serialization.cs index 3385831f..a4f3c1f7 100644 --- a/src/OpenIddict.Server/OpenIddictServerEvents.Serialization.cs +++ b/src/OpenIddict.Server/OpenIddictServerEvents.Serialization.cs @@ -48,11 +48,6 @@ namespace OpenIddict.Server /// public JsonWebTokenHandler SecurityTokenHandler { get; set; } - /// - /// Gets or sets the issuer address. - /// - public Uri Issuer { get; set; } - /// /// Gets or sets the token returned to the client application. /// diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs index 5f9b12ff..67a8622f 100644 --- a/src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs +++ b/src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs @@ -123,11 +123,6 @@ namespace OpenIddict.Server /// public string GivenName { get; set; } - /// - /// Gets or sets the value used for the "iss" claim. - /// - public string Issuer { get; set; } - /// /// Gets or sets the value used for the "phone_number" claim. /// Note: this value should only be populated if the "phone" diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.cs b/src/OpenIddict.Server/OpenIddictServerEvents.cs index 216974ce..4b61cb79 100644 --- a/src/OpenIddict.Server/OpenIddictServerEvents.cs +++ b/src/OpenIddict.Server/OpenIddictServerEvents.cs @@ -33,6 +33,15 @@ namespace OpenIddict.Server /// public OpenIddictServerTransaction Transaction { get; } + /// + /// Gets or sets the issuer address associated with the current transaction, if available. + /// + public Uri Issuer + { + get => Transaction.Issuer; + set => Transaction.Issuer = value; + } + /// /// Gets or sets the endpoint type that handled the request, if applicable. /// diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs index 9da7e27f..717c9907 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs @@ -40,7 +40,6 @@ namespace OpenIddict.Server /* * Configuration request handling: */ - AttachIssuer.Descriptor, AttachEndpoints.Descriptor, AttachGrantTypes.Descriptor, AttachResponseModes.Descriptor, @@ -357,43 +356,6 @@ namespace OpenIddict.Server } } - /// - /// Contains the logic responsible of attaching the issuer URL to the provider discovery document. - /// - public class AttachIssuer : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .UseSingletonHandler() - .SetOrder(int.MinValue + 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (context.Options.Issuer != null) - { - context.Issuer = context.Options.Issuer; - } - - return default; - } - } - /// /// Contains the logic responsible of attaching the endpoint URLs to the provider discovery document. /// @@ -405,7 +367,7 @@ namespace OpenIddict.Server public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order + 1_000) + .SetOrder(int.MaxValue - 100_000) .Build(); /// diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs index a395884a..c2dd1196 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs @@ -270,7 +270,7 @@ namespace OpenIddict.Server var response = new OpenIddictResponse { [Claims.Active] = true, - [Claims.Issuer] = notification.Issuer, + [Claims.Issuer] = notification.Issuer?.AbsoluteUri, [Claims.Username] = notification.Username, [Claims.Subject] = notification.Subject, [Claims.Scope] = string.Join(" ", notification.Scopes), @@ -984,7 +984,6 @@ namespace OpenIddict.Server throw new ArgumentNullException(nameof(context)); } - context.Issuer = context.Options.Issuer?.AbsoluteUri; context.TokenId = context.Principal.GetTokenId(); context.TokenUsage = context.Principal.GetTokenUsage(); context.Subject = context.Principal.GetClaim(Claims.Subject); diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Serialization.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Serialization.cs index 837b7777..4977ee76 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Serialization.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Serialization.cs @@ -285,7 +285,6 @@ namespace OpenIddict.Server context.EncryptingCredentials = context.Options.EncryptionCredentials.FirstOrDefault( credentials => credentials.Key is SymmetricSecurityKey); - context.Issuer = context.Options.Issuer; context.SecurityTokenHandler = context.Options.AccessTokenHandler; context.SigningCredentials = context.Options.SigningCredentials.FirstOrDefault( credentials => credentials.Key is SymmetricSecurityKey) ?? context.Options.SigningCredentials.First(); @@ -333,7 +332,6 @@ namespace OpenIddict.Server } context.EncryptingCredentials = context.Options.EncryptionCredentials[0]; - context.Issuer = context.Options.Issuer; context.SecurityTokenHandler = context.Options.AuthorizationCodeHandler; context.SigningCredentials = context.Options.SigningCredentials.FirstOrDefault( credentials => credentials.Key is SymmetricSecurityKey) ?? context.Options.SigningCredentials.First(); @@ -375,7 +373,6 @@ namespace OpenIddict.Server throw new InvalidOperationException("No suitable signing credentials could be found."); } - context.Issuer = context.Options.Issuer; context.SecurityTokenHandler = context.Options.IdentityTokenHandler; context.SigningCredentials = context.Options.SigningCredentials.First( credentials => credentials.Key is AsymmetricSecurityKey); @@ -423,7 +420,6 @@ namespace OpenIddict.Server } context.EncryptingCredentials = context.Options.EncryptionCredentials[0]; - context.Issuer = context.Options.Issuer; context.SecurityTokenHandler = context.Options.AuthorizationCodeHandler; context.SigningCredentials = context.Options.SigningCredentials.FirstOrDefault( credentials => credentials.Key is SymmetricSecurityKey) ?? context.Options.SigningCredentials.First(); @@ -469,7 +465,7 @@ namespace OpenIddict.Server context.TokenValidationParameters.TokenDecryptionKeys = context.Options.EncryptionCredentials .Select(credentials => credentials.Key) .Where(key => key is SymmetricSecurityKey); - context.TokenValidationParameters.ValidIssuer = context.Options.Issuer?.AbsoluteUri; + context.TokenValidationParameters.ValidIssuer = context.Issuer?.AbsoluteUri; context.TokenValidationParameters.ValidateAudience = false; context.TokenValidationParameters.ValidateLifetime = false; @@ -513,7 +509,7 @@ namespace OpenIddict.Server context.TokenValidationParameters.RoleClaimType = Claims.Role; context.TokenValidationParameters.TokenDecryptionKeys = context.Options.EncryptionCredentials .Select(credentials => credentials.Key); - context.TokenValidationParameters.ValidIssuer = context.Options.Issuer?.AbsoluteUri; + context.TokenValidationParameters.ValidIssuer = context.Issuer?.AbsoluteUri; context.TokenValidationParameters.ValidateAudience = false; context.TokenValidationParameters.ValidateLifetime = false; @@ -556,7 +552,7 @@ namespace OpenIddict.Server .OfType(); context.TokenValidationParameters.NameClaimType = Claims.Name; context.TokenValidationParameters.RoleClaimType = Claims.Role; - context.TokenValidationParameters.ValidIssuer = context.Options.Issuer?.AbsoluteUri; + context.TokenValidationParameters.ValidIssuer = context.Issuer?.AbsoluteUri; context.TokenValidationParameters.ValidateAudience = false; context.TokenValidationParameters.ValidateLifetime = false; @@ -600,7 +596,7 @@ namespace OpenIddict.Server context.TokenValidationParameters.RoleClaimType = Claims.Role; context.TokenValidationParameters.TokenDecryptionKeys = context.Options.EncryptionCredentials .Select(credentials => credentials.Key); - context.TokenValidationParameters.ValidIssuer = context.Options.Issuer?.AbsoluteUri; + context.TokenValidationParameters.ValidIssuer = context.Issuer?.AbsoluteUri; context.TokenValidationParameters.ValidateAudience = false; context.TokenValidationParameters.ValidateLifetime = false; diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs index cc1d1284..77be8653 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs @@ -44,7 +44,6 @@ namespace OpenIddict.Server /* * Userinfo request handling: */ - AttachIssuer.Descriptor, AttachPrincipal.Descriptor, AttachAudiences.Descriptor, AttachClaims.Descriptor); @@ -264,7 +263,7 @@ namespace OpenIddict.Server [Claims.EmailVerified] = notification.EmailVerified, [Claims.FamilyName] = notification.FamilyName, [Claims.GivenName] = notification.GivenName, - [Claims.Issuer] = notification.Issuer, + [Claims.Issuer] = notification.Issuer?.AbsoluteUri, [Claims.PhoneNumber] = notification.PhoneNumber, [Claims.PhoneNumberVerified] = notification.PhoneNumberVerified, [Claims.PreferredUsername] = notification.PreferredUsername, @@ -498,43 +497,6 @@ namespace OpenIddict.Server } } - /// - /// Contains the logic responsible of attaching the issuer URL to the userinfo response. - /// - public class AttachIssuer : IOpenIddictServerHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictServerHandlerDescriptor Descriptor { get; } - = OpenIddictServerHandlerDescriptor.CreateBuilder() - .UseSingletonHandler() - .SetOrder(AttachPrincipal.Descriptor.Order + 100_000) - .Build(); - - /// - /// Processes the event. - /// - /// The context associated with the event to process. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (context.Options.Issuer != null) - { - context.Issuer = context.Options.Issuer.AbsoluteUri; - } - - return default; - } - } - /// /// Contains the logic responsible of attaching the audiences to the userinfo response. /// @@ -546,7 +508,7 @@ namespace OpenIddict.Server public static OpenIddictServerHandlerDescriptor Descriptor { get; } = OpenIddictServerHandlerDescriptor.CreateBuilder() .UseSingletonHandler() - .SetOrder(AttachIssuer.Descriptor.Order + 100_000) + .SetOrder(AttachPrincipal.Descriptor.Order + 1_000) .Build(); /// diff --git a/src/OpenIddict.Server/OpenIddictServerProvider.cs b/src/OpenIddict.Server/OpenIddictServerProvider.cs index 857c9a64..c6e339bf 100644 --- a/src/OpenIddict.Server/OpenIddictServerProvider.cs +++ b/src/OpenIddict.Server/OpenIddictServerProvider.cs @@ -38,6 +38,7 @@ namespace OpenIddict.Server public ValueTask CreateTransactionAsync() => new ValueTask(new OpenIddictServerTransaction { + Issuer = _options.CurrentValue.Issuer, Logger = _logger, Options = _options.CurrentValue }); diff --git a/src/OpenIddict.Server/OpenIddictServerTransaction.cs b/src/OpenIddict.Server/OpenIddictServerTransaction.cs index 1e7e5afe..681910ba 100644 --- a/src/OpenIddict.Server/OpenIddictServerTransaction.cs +++ b/src/OpenIddict.Server/OpenIddictServerTransaction.cs @@ -21,6 +21,11 @@ namespace OpenIddict.Server /// public OpenIddictServerEndpointType EndpointType { get; set; } + /// + /// Gets or sets the issuer address associated with the current transaction, if available. + /// + public Uri Issuer { get; set; } + /// /// Gets or sets the logger associated with the current request. ///