From 55cd0e94a8034d08270f7edbb8febc1295c712aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Mon, 9 Jun 2025 23:32:06 +0200 Subject: [PATCH] Update all the token type validation delegates to assume that tokens that don't have a "typ" header are generic JSON Web Tokens --- src/OpenIddict.Client/OpenIddictClientOptions.cs | 8 +++++++- src/OpenIddict.Client/OpenIddictClientRegistration.cs | 8 +++++++- .../OpenIddictServerHandlers.Protection.cs | 6 ++++++ src/OpenIddict.Server/OpenIddictServerOptions.cs | 5 ++--- src/OpenIddict.Validation/OpenIddictValidationOptions.cs | 5 ++--- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/OpenIddict.Client/OpenIddictClientOptions.cs b/src/OpenIddict.Client/OpenIddictClientOptions.cs index 8f396b4e..7edf7e96 100644 --- a/src/OpenIddict.Client/OpenIddictClientOptions.cs +++ b/src/OpenIddict.Client/OpenIddictClientOptions.cs @@ -113,9 +113,15 @@ public sealed class OpenIddictClientOptions ClockSkew = TimeSpan.Zero, NameClaimType = Claims.Name, RoleClaimType = Claims.Role, - // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. TypeValidator = static (type, token, parameters) => { + // Assume that tokens that don't have an explicit "typ" header attached are generic JSON Web Tokens. + if (string.IsNullOrEmpty(type)) + { + type = JsonWebTokenTypes.GenericJsonWebToken; + } + + // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. if (parameters.ValidTypes is not null && parameters.ValidTypes.Any() && !parameters.ValidTypes.Contains(type, StringComparer.OrdinalIgnoreCase)) { diff --git a/src/OpenIddict.Client/OpenIddictClientRegistration.cs b/src/OpenIddict.Client/OpenIddictClientRegistration.cs index b77572e4..933f9121 100644 --- a/src/OpenIddict.Client/OpenIddictClientRegistration.cs +++ b/src/OpenIddict.Client/OpenIddictClientRegistration.cs @@ -190,9 +190,15 @@ public sealed class OpenIddictClientRegistration ClockSkew = TimeSpan.Zero, NameClaimType = Claims.Name, RoleClaimType = Claims.Role, - // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. TypeValidator = static (type, token, parameters) => { + // Assume that tokens that don't have an explicit "typ" header attached are generic JSON Web Tokens. + if (string.IsNullOrEmpty(type)) + { + type = JsonWebTokenTypes.GenericJsonWebToken; + } + + // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. if (parameters.ValidTypes is not null && parameters.ValidTypes.Any() && !parameters.ValidTypes.Contains(type, StringComparer.OrdinalIgnoreCase)) { diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs index 286dcb18..2f9845b1 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs @@ -119,6 +119,12 @@ public static partial class OpenIddictServerHandlers { TypeValidator = static (type, token, parameters) => { + // Assume that tokens that don't have an explicit "typ" header attached are generic JSON Web Tokens. + if (string.IsNullOrEmpty(type)) + { + type = JsonWebTokenTypes.GenericJsonWebToken; + } + // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. if (parameters.ValidTypes is not null && parameters.ValidTypes.Any() && !parameters.ValidTypes.Contains(type, StringComparer.OrdinalIgnoreCase)) diff --git a/src/OpenIddict.Server/OpenIddictServerOptions.cs b/src/OpenIddict.Server/OpenIddictServerOptions.cs index 983b1681..58f9aaad 100644 --- a/src/OpenIddict.Server/OpenIddictServerOptions.cs +++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs @@ -154,11 +154,10 @@ public sealed class OpenIddictServerOptions }; } - // At this point, throw an exception if the type cannot be resolved from the "typ" header - // (provided via the type delegate parameter) or inferred from the token_usage claim. + // Assume that tokens that don't have an explicit "typ" header attached are generic JSON Web Tokens. if (string.IsNullOrEmpty(type)) { - throw new SecurityTokenInvalidTypeException(SR.GetResourceString(SR.ID0270)); + type = JsonWebTokenTypes.GenericJsonWebToken; } // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons. diff --git a/src/OpenIddict.Validation/OpenIddictValidationOptions.cs b/src/OpenIddict.Validation/OpenIddictValidationOptions.cs index 687d12d3..70e5de17 100644 --- a/src/OpenIddict.Validation/OpenIddictValidationOptions.cs +++ b/src/OpenIddict.Validation/OpenIddictValidationOptions.cs @@ -185,11 +185,10 @@ public sealed class OpenIddictValidationOptions }; } - // At this point, throw an exception if the type cannot be resolved from the "typ" header - // (provided via the type delegate parameter) or inferred from the token_usage claim. + // Assume that tokens that don't have an explicit "typ" header attached are generic JSON Web Tokens. if (string.IsNullOrEmpty(type)) { - throw new SecurityTokenInvalidTypeException(SR.GetResourceString(SR.ID0270)); + type = JsonWebTokenTypes.GenericJsonWebToken; } // Note: unlike IdentityModel, this custom validator deliberately uses case-insensitive comparisons.