diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
index 6a98612a..df755fef 100644
--- a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
+++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
@@ -110,7 +110,7 @@ public static partial class OpenIddictClientHandlers
var parameters = registration!.TokenValidationParameters.Clone();
- parameters.ValidIssuer ??= configuration.Issuer?.AbsoluteUri ?? registration.Issuer?.AbsoluteUri;
+ parameters.ValidIssuer ??= configuration.Issuer?.OriginalString;
parameters.ValidateIssuer = !string.IsNullOrEmpty(parameters.ValidIssuer);
// Combine the signing keys registered statically in the token validation parameters
diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Userinfo.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Userinfo.cs
index e2150491..0ee86817 100644
--- a/src/OpenIddict.Client/OpenIddictClientHandlers.Userinfo.cs
+++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Userinfo.cs
@@ -97,7 +97,7 @@ public static partial class OpenIddictClientHandlers
.Build();
///
- public ValueTask HandleAsync(HandleUserinfoResponseContext context)
+ public async ValueTask HandleAsync(HandleUserinfoResponseContext context)
{
if (context is null)
{
@@ -107,7 +107,16 @@ public static partial class OpenIddictClientHandlers
// Ignore the response instance if a userinfo token was extracted.
if (!string.IsNullOrEmpty(context.UserinfoToken))
{
- return default;
+ return;
+ }
+
+ var configuration = await context.Registration.ConfigurationManager.GetConfigurationAsync(default) ??
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0140));
+
+ // Ensure the issuer resolved from the configuration matches the expected value.
+ if (configuration.Issuer != context.Issuer)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0307));
}
// Create a new claims-based identity using the same authentication type
@@ -120,7 +129,7 @@ public static partial class OpenIddictClientHandlers
// Resolve the issuer that will be attached to the claims created by this handler.
// Note: at this stage, the optional issuer extracted from the response is assumed
// to be valid, as it is guarded against unknown values by the ValidateIssuer handler.
- var issuer = (string?) context.Response[Claims.Issuer] ?? context.Issuer?.AbsoluteUri ?? ClaimsIdentity.DefaultIssuer;
+ var issuer = (string?) context.Response[Claims.Issuer] ?? configuration.Issuer!.OriginalString;
foreach (var parameter in context.Response.GetParameters())
{
@@ -196,8 +205,6 @@ public static partial class OpenIddictClientHandlers
context.Principal = new ClaimsPrincipal(identity);
- return default;
-
static string GetClaimValueType(JsonValueKind kind) => kind switch
{
JsonValueKind.True or JsonValueKind.False => ClaimValueTypes.Boolean,
diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.cs
index d0050572..0a50834f 100644
--- a/src/OpenIddict.Client/OpenIddictClientHandlers.cs
+++ b/src/OpenIddict.Client/OpenIddictClientHandlers.cs
@@ -75,7 +75,7 @@ public static partial class OpenIddictClientHandlers
ValidateRequiredUserinfoToken.Descriptor,
ValidateUserinfoToken.Descriptor,
ValidateUserinfoTokenWellknownClaims.Descriptor,
- ValidateUserinfoTokenWellknownSubject.Descriptor,
+ ValidateUserinfoTokenSubject.Descriptor,
/*
* Challenge processing:
@@ -2663,7 +2663,7 @@ public static partial class OpenIddictClientHandlers
///
/// Contains the logic responsible of validating the subject claim contained in the userinfo token.
///
- public class ValidateUserinfoTokenWellknownSubject : IOpenIddictClientHandler
+ public class ValidateUserinfoTokenSubject : IOpenIddictClientHandler
{
///
/// Gets the default descriptor definition assigned to this handler.
@@ -2672,7 +2672,7 @@ public static partial class OpenIddictClientHandlers
= OpenIddictClientHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .UseSingletonHandler()
+ .UseSingletonHandler()
.SetOrder(ValidateUserinfoTokenWellknownClaims.Descriptor.Order + 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
.Build();
diff --git a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs
index f8ae3526..be160ea1 100644
--- a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs
+++ b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs
@@ -15,7 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection;
public class OpenIddictValidationServerIntegrationBuilder
{
///
- /// Initializes a new instance of .
+ /// Initializes a new instance of .
///
/// The services collection.
public OpenIddictValidationServerIntegrationBuilder(IServiceCollection services)
diff --git a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs
index 7d0c5a5f..bd8b74be 100644
--- a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs
+++ b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs
@@ -22,7 +22,7 @@ public static class OpenIddictValidationServerIntegrationExtensions
///
/// The services builder used by OpenIddict to register new services.
/// This extension can be safely called multiple times.
- /// The .
+ /// The .
public static OpenIddictValidationServerIntegrationBuilder UseLocalServer(this OpenIddictValidationBuilder builder)
{
if (builder is null)
@@ -47,7 +47,7 @@ public static class OpenIddictValidationServerIntegrationExtensions
/// The services builder used by OpenIddict to register new services.
/// The configuration delegate used to configure the validation services.
/// This extension can be safely called multiple times.
- /// The .
+ /// The .
public static OpenIddictValidationBuilder UseLocalServer(
this OpenIddictValidationBuilder builder, Action configuration)
{
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
index 6def980c..6957ef36 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
@@ -351,13 +351,22 @@ public static partial class OpenIddictValidationHandlers
.Build();
///
- public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
+ public async ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
+ var configuration = await context.Options.ConfigurationManager.GetConfigurationAsync(default) ??
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0140));
+
+ // Ensure the issuer resolved from the configuration matches the expected value.
+ if (configuration is not null && configuration.Issuer != context.Issuer)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0307));
+ }
+
// Create a new claims-based identity using the same authentication type
// and the name/role claims as the one used by IdentityModel for JWT tokens.
var identity = new ClaimsIdentity(
@@ -368,7 +377,9 @@ public static partial class OpenIddictValidationHandlers
// Resolve the issuer that will be attached to the claims created by this handler.
// Note: at this stage, the optional issuer extracted from the response is assumed
// to be valid, as it is guarded against unknown values by the ValidateIssuer handler.
- var issuer = (string?) context.Response[Claims.Issuer] ?? context.Issuer?.AbsoluteUri ?? ClaimsIdentity.DefaultIssuer;
+ var issuer = (string?) context.Response[Claims.Issuer] ??
+ configuration?.Issuer?.OriginalString ??
+ context.Issuer?.OriginalString ?? ClaimsIdentity.DefaultIssuer;
foreach (var parameter in context.Response.GetParameters())
{
@@ -444,8 +455,6 @@ public static partial class OpenIddictValidationHandlers
context.Principal = new ClaimsPrincipal(identity);
- return default;
-
static string GetClaimValueType(JsonValueKind kind) => kind switch
{
JsonValueKind.True or JsonValueKind.False => ClaimValueTypes.Boolean,
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
index 115ced33..9af9bbde 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
@@ -70,7 +70,7 @@ public static partial class OpenIddictValidationHandlers
// Clone the token validation parameters and set the issuer using the value found in the
// OpenID Connect server configuration (that can be static or retrieved using discovery).
var parameters = context.Options.TokenValidationParameters.Clone();
- parameters.ValidIssuer ??= configuration.Issuer?.AbsoluteUri ?? context.Issuer?.AbsoluteUri;
+ parameters.ValidIssuer ??= configuration.Issuer?.OriginalString;
parameters.ValidateIssuer = !string.IsNullOrEmpty(parameters.ValidIssuer);
// Combine the signing keys registered statically in the token validation parameters