1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Change Type Validation Default

NimbusJwtDecoder and NimbusReactiveJwtDecoder now use
Spring Security's JwtTypeValidator by default instead
of Nimbus's type validator.

Closes gh-17181
This commit is contained in:
Josh Cummings
2025-05-27 13:13:54 -06:00
parent 37a814bc29
commit 6d3b54df21
9 changed files with 111 additions and 37 deletions
@@ -75,8 +75,8 @@ public final class JwtValidators {
* supplied
*/
public static OAuth2TokenValidator<Jwt> createDefault() {
return new DelegatingOAuth2TokenValidator<>(
Arrays.asList(new JwtTimestampValidator(), new X509CertificateThumbprintValidator(
return new DelegatingOAuth2TokenValidator<>(Arrays.asList(JwtTypeValidator.jwt(), new JwtTimestampValidator(),
new X509CertificateThumbprintValidator(
X509CertificateThumbprintValidator.DEFAULT_X509_CERTIFICATE_SUPPLIER)));
}
@@ -104,6 +104,10 @@ public final class JwtValidators {
if (jwtTimestampValidator == null) {
tokenValidators.add(0, new JwtTimestampValidator());
}
JwtTypeValidator typeValidator = CollectionUtils.findValueOfType(tokenValidators, JwtTypeValidator.class);
if (typeValidator == null) {
tokenValidators.add(0, JwtTypeValidator.jwt());
}
return new DelegatingOAuth2TokenValidator<>(tokenValidators);
}
@@ -279,7 +279,7 @@ public final class NimbusJwtDecoder implements JwtDecoder {
private Function<JWKSource<SecurityContext>, Set<JWSAlgorithm>> defaultAlgorithms = (source) -> Set
.of(JWSAlgorithm.RS256);
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private final Set<SignatureAlgorithm> signatureAlgorithms = new HashSet<>();
@@ -548,7 +548,7 @@ public final class NimbusJwtDecoder implements JwtDecoder {
private JWSAlgorithm jwsAlgorithm;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private final RSAPublicKey key;
@@ -680,7 +680,7 @@ public final class NimbusJwtDecoder implements JwtDecoder {
private JWSAlgorithm jwsAlgorithm = JWSAlgorithm.HS256;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer;
@@ -324,7 +324,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder {
private Function<ReactiveRemoteJWKSource, Mono<Set<JWSAlgorithm>>> defaultAlgorithms = (source) -> Mono
.just(Set.of(JWSAlgorithm.RS256));
private JOSEObjectTypeVerifier<JWKSecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<JWKSecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private Set<SignatureAlgorithm> signatureAlgorithms = new HashSet<>();
@@ -547,7 +547,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder {
private JWSAlgorithm jwsAlgorithm;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer;
@@ -682,7 +682,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder {
private JWSAlgorithm jwsAlgorithm = JWSAlgorithm.HS256;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer;
@@ -814,7 +814,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder {
private JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256;
private JOSEObjectTypeVerifier<JWKSecurityContext> typeVerifier = JWT_TYPE_VERIFIER;
private JOSEObjectTypeVerifier<JWKSecurityContext> typeVerifier = NO_TYPE_VERIFIER;
private Consumer<ConfigurableJWTProcessor<JWKSecurityContext>> jwtProcessorCustomizer;
@@ -62,7 +62,8 @@ public class JwtValidatorsTests {
assertThat(containsByType(validator, JwtTimestampValidator.class)).isTrue();
assertThat(containsByType(validator, X509CertificateThumbprintValidator.class)).isTrue();
assertThat(Objects.requireNonNull(tokenValidators).size()).isEqualTo(2);
assertThat(containsByType(validator, JwtTypeValidator.class)).isTrue();
assertThat(Objects.requireNonNull(tokenValidators).size()).isEqualTo(3);
}
@Test
@@ -458,10 +458,8 @@ public class NimbusJwtDecoderTests {
// @formatter:off
NimbusJwtDecoder decoder = NimbusJwtDecoder.withPublicKey(publicKey)
.signatureAlgorithm(SignatureAlgorithm.RS256)
.jwtProcessorCustomizer((p) -> p
.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>(new JOSEObjectType("JWS")))
)
.build();
decoder.setJwtValidator(JwtValidators.createDefaultWithValidators(new JwtTypeValidator("JWS")));
// @formatter:on
assertThat(decoder.decode(signedJwt.serialize()).hasClaim(JwtClaimNames.EXP)).isNotNull();
}
@@ -575,10 +573,8 @@ public class NimbusJwtDecoderTests {
// @formatter:off
NimbusJwtDecoder decoder = NimbusJwtDecoder.withSecretKey(secretKey)
.macAlgorithm(MacAlgorithm.HS256)
.jwtProcessorCustomizer((p) -> p
.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>(new JOSEObjectType("JWS")))
)
.build();
decoder.setJwtValidator(JwtValidators.createDefaultWithValidators(new JwtTypeValidator("JWS")));
// @formatter:on
assertThat(decoder.decode(signedJwt.serialize()).hasClaim(JwtClaimNames.EXP)).isNotNull();
}
@@ -837,6 +833,7 @@ public class NimbusJwtDecoderTests {
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(TestKeys.DEFAULT_PUBLIC_KEY)
.validateType(false)
.build();
jwtDecoder.setJwtValidator((jwt) -> OAuth2TokenValidatorResult.success());
RSAPrivateKey privateKey = TestKeys.DEFAULT_PRIVATE_KEY;
SignedJWT jwt = signedJwt(privateKey,
new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JOSE).build(),
@@ -849,6 +846,7 @@ public class NimbusJwtDecoderTests {
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(TestKeys.DEFAULT_SECRET_KEY)
.validateType(false)
.build();
jwtDecoder.setJwtValidator((jwt) -> OAuth2TokenValidatorResult.success());
SignedJWT jwt = signedJwt(TestKeys.DEFAULT_SECRET_KEY,
new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JOSE).build(),
new JWTClaimsSet.Builder().subject("subject").build());
@@ -667,6 +667,7 @@ public class NimbusReactiveJwtDecoderTests {
NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withPublicKey(TestKeys.DEFAULT_PUBLIC_KEY)
.validateType(false)
.build();
jwtDecoder.setJwtValidator((jwt) -> OAuth2TokenValidatorResult.success());
RSAPrivateKey privateKey = TestKeys.DEFAULT_PRIVATE_KEY;
SignedJWT jwt = signedJwt(privateKey,
new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JOSE).build(),
@@ -679,6 +680,7 @@ public class NimbusReactiveJwtDecoderTests {
NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withSecretKey(TestKeys.DEFAULT_SECRET_KEY)
.validateType(false)
.build();
jwtDecoder.setJwtValidator((jwt) -> OAuth2TokenValidatorResult.success());
SignedJWT jwt = signedJwt(TestKeys.DEFAULT_SECRET_KEY,
new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JOSE).build(),
new JWTClaimsSet.Builder().subject("subject").build());
@@ -693,6 +695,7 @@ public class NimbusReactiveJwtDecoderTests {
NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withJwkSource((jwt) -> Flux.just(jwk))
.validateType(false)
.build();
jwtDecoder.setJwtValidator((jwt) -> OAuth2TokenValidatorResult.success());
SignedJWT jwt = signedJwt(TestKeys.DEFAULT_PRIVATE_KEY,
new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JOSE).build(),
new JWTClaimsSet.Builder().subject("subject").build());