| 
					
				 | 
			
			
				@@ -32,6 +32,7 @@ import javax.crypto.SecretKey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.Header; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.JOSEException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.nimbusds.jose.JOSEObjectType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.JWSAlgorithm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.JWSHeader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.jwk.JWK; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -39,6 +40,8 @@ import com.nimbusds.jose.jwk.JWKMatcher; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.jwk.JWKSelector; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.jwk.source.JWKSecurityContextJWKSet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.proc.BadJOSEException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.nimbusds.jose.proc.JOSEObjectTypeVerifier; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.proc.JWKSecurityContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.proc.JWSKeySelector; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.nimbusds.jose.proc.JWSVerificationKeySelector; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -308,6 +311,12 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public static final class JwkSetUriReactiveJwtDecoderBuilder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<JWKSecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				JOSEObjectType.JWT, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<JWKSecurityContext> NO_TYPE_VERIFIER = (header, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private static final Duration FOREVER = Duration.ofMillis(Long.MAX_VALUE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private Function<WebClient, Mono<String>> jwkSetUri; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -315,6 +324,8 @@ 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 Set<SignatureAlgorithm> signatureAlgorithms = new HashSet<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private WebClient webClient = WebClient.create(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -349,6 +360,55 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Whether to use Nimbus's typ header verification. This is {@code true} by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * default, however it may change to {@code false} in a future major release. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * By turning off this feature, {@link NimbusReactiveJwtDecoder} expects 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * applications to check the {@code typ} header themselves in order to determine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * what kind of validation is needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * This is done for you when you use {@link JwtValidators} to construct a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * validator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * That means that this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withIssuerLocation(issuer).build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Is equivalent to this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withIssuerLocation(issuer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     		new JwtIssuerValidator(issuer), JwtTypeValidator.jwt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The difference is that by setting this to {@code false}, it allows you to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * provide validation by type, like for {@code at+jwt}: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withIssuerLocation(issuer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(new MyAtJwtValidator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @param shouldValidateTypHeader whether Nimbus should validate the typ header or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @return a {@link JwkSetUriReactiveJwtDecoderBuilder} for further configurations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @since 6.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		public JwkSetUriReactiveJwtDecoderBuilder validateType(boolean shouldValidateTypHeader) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this.typeVerifier = shouldValidateTypHeader ? JWT_TYPE_VERIFIER : NO_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * Configure the list of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target= 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -435,13 +495,14 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			Mono<Tuple2<ConfigurableJWTProcessor<JWKSecurityContext>, Function<JWSAlgorithm, Boolean>>> jwtProcessorMono = jwsKeySelector 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				.flatMap((selector) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					jwtProcessor.setJWSKeySelector(selector); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					jwtProcessor.setJWSTypeVerifier(this.typeVerifier); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					return this.jwtProcessorCustomizer.apply(source, jwtProcessor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				.map((processor) -> Tuples.of(processor, getExpectedJwsAlgorithms(processor.getJWSKeySelector()))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				.cache((processor) -> FOREVER, (ex) -> Duration.ZERO, () -> Duration.ZERO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return (jwt) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				return jwtProcessorMono.flatMap((tuple) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					JWTProcessor<JWKSecurityContext> processor = tuple.getT1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					ConfigurableJWTProcessor<JWKSecurityContext> processor = tuple.getT1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					Function<JWSAlgorithm, Boolean> expectedJwsAlgorithms = tuple.getT2(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					JWKSelector selector = createSelector(expectedJwsAlgorithms, jwt.getHeader()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					return source.get(selector) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -476,10 +537,18 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public static final class PublicKeyReactiveJwtDecoderBuilder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<SecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				JOSEObjectType.JWT, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<SecurityContext> NO_TYPE_VERIFIER = (header, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private final RSAPublicKey key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private JWSAlgorithm jwsAlgorithm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private PublicKeyReactiveJwtDecoderBuilder(RSAPublicKey key) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -505,6 +574,56 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Whether to use Nimbus's typ header verification. This is {@code true} by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * default, however it may change to {@code false} in a future major release. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * By turning off this feature, {@link NimbusReactiveJwtDecoder} expects 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * applications to check the {@code typ} header themselves in order to determine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * what kind of validation is needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * This is done for you when you use {@link JwtValidators} to construct a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * validator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * That means that this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withIssuerLocation(issuer).build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Is equivalent to this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withPublicKey(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     		new JwtIssuerValidator(issuer), JwtTypeValidator.jwt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     		new JwtIssuerValidator(issuer), JwtTypeValidator.jwt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The difference is that by setting this to {@code false}, it allows you to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * provide validation by type, like for {@code at+jwt}: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withPublicKey(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(new MyAtJwtValidator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @param shouldValidateTypHeader whether Nimbus should validate the typ header or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @return a {@link PublicKeyReactiveJwtDecoderBuilder} for further configurations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @since 6.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		public PublicKeyReactiveJwtDecoderBuilder validateType(boolean shouldValidateTypHeader) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this.typeVerifier = shouldValidateTypHeader ? JWT_TYPE_VERIFIER : NO_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * Use the given {@link Consumer} to customize the {@link JWTProcessor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * ConfigurableJWTProcessor} before passing it to the build 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -535,6 +654,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			JWSKeySelector<SecurityContext> jwsKeySelector = new SingleKeyJWSKeySelector<>(this.jwsAlgorithm, this.key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWSKeySelector(jwsKeySelector); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			jwtProcessor.setJWSTypeVerifier(this.typeVerifier); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// Spring Security validates the claim set independent from Nimbus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -552,10 +672,18 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public static final class SecretKeyReactiveJwtDecoderBuilder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<SecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				JOSEObjectType.JWT, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<SecurityContext> NO_TYPE_VERIFIER = (header, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private final SecretKey secretKey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private JWSAlgorithm jwsAlgorithm = JWSAlgorithm.HS256; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private JOSEObjectTypeVerifier<SecurityContext> typeVerifier = JWT_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private SecretKeyReactiveJwtDecoderBuilder(SecretKey secretKey) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -582,6 +710,55 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Whether to use Nimbus's typ header verification. This is {@code true} by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * default, however it may change to {@code false} in a future major release. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * By turning off this feature, {@link NimbusReactiveJwtDecoder} expects 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * applications to check the {@code typ} header themselves in order to determine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * what kind of validation is needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * This is done for you when you use {@link JwtValidators} to construct a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * validator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * That means that this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withIssuerLocation(issuer).build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Is equivalent to this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withSecretKey(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     		new JwtIssuerValidator(issuer), JwtTypeValidator.jwt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The difference is that by setting this to {@code false}, it allows you to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * provide validation by type, like for {@code at+jwt}: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withSecretKey(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(new MyAtJwtValidator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @param shouldValidateTypHeader whether Nimbus should validate the typ header or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @return a {@link PublicKeyReactiveJwtDecoderBuilder} for further configurations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @since 6.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		public SecretKeyReactiveJwtDecoderBuilder validateType(boolean shouldValidateTypHeader) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this.typeVerifier = shouldValidateTypHeader ? JWT_TYPE_VERIFIER : NO_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * Use the given {@link Consumer} to customize the {@link JWTProcessor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * ConfigurableJWTProcessor} before passing it to the build 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -610,6 +787,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					this.secretKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWSKeySelector(jwsKeySelector); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			jwtProcessor.setJWSTypeVerifier(this.typeVerifier); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// Spring Security validates the claim set independent from Nimbus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -626,10 +804,18 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public static final class JwkSourceReactiveJwtDecoderBuilder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<JWKSecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				JOSEObjectType.JWT, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private static final JOSEObjectTypeVerifier<JWKSecurityContext> NO_TYPE_VERIFIER = (header, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private final Function<SignedJWT, Flux<JWK>> jwkSource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		private JOSEObjectTypeVerifier<JWKSecurityContext> typeVerifier = JWT_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private Consumer<ConfigurableJWTProcessor<JWKSecurityContext>> jwtProcessorCustomizer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		private JwkSourceReactiveJwtDecoderBuilder(Function<SignedJWT, Flux<JWK>> jwkSource) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -652,6 +838,55 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Whether to use Nimbus's typ header verification. This is {@code true} by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * default, however it may change to {@code false} in a future major release. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * By turning off this feature, {@link NimbusReactiveJwtDecoder} expects 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * applications to check the {@code typ} header themselves in order to determine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * what kind of validation is needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * This is done for you when you use {@link JwtValidators} to construct a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * validator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * That means that this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withJwkSource(issuer).build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Is equivalent to this: <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withJwkSource(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     		new JwtIssuerValidator(issuer), JwtTypeValidator.jwt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The difference is that by setting this to {@code false}, it allows you to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * provide validation by type, like for {@code at+jwt}: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withJwkSource(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .validateType(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *         .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 *     jwtDecoder.setJwtValidator(new MyAtJwtValidator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @param shouldValidateTypHeader whether Nimbus should validate the typ header or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @return a {@link JwkSourceReactiveJwtDecoderBuilder} for further configurations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * @since 6.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		public JwkSourceReactiveJwtDecoderBuilder validateType(boolean shouldValidateTypHeader) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this.typeVerifier = shouldValidateTypHeader ? JWT_TYPE_VERIFIER : NO_TYPE_VERIFIER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * Use the given {@link Consumer} to customize the {@link JWTProcessor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 * ConfigurableJWTProcessor} before passing it to the build 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -681,6 +916,7 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					jwkSource); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			DefaultJWTProcessor<JWKSecurityContext> jwtProcessor = new DefaultJWTProcessor<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWSKeySelector(jwsKeySelector); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			jwtProcessor.setJWSTypeVerifier(this.typeVerifier); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			this.jwtProcessorCustomizer.accept(jwtProcessor); 
			 |