|
@@ -545,108 +545,6 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * A builder for creating {@link NimbusJwtDecoder} instances based on a
|
|
|
- * {@code JWKSource}.
|
|
|
- */
|
|
|
- public static final class JwkSourceJwtDecoderBuilder {
|
|
|
-
|
|
|
- private static final JOSEObjectTypeVerifier<SecurityContext> NO_TYPE_VERIFIER = (header, context) -> {
|
|
|
- };
|
|
|
-
|
|
|
- private final Function<JWKSource<SecurityContext>, Set<JWSAlgorithm>> defaultAlgorithms = (source) -> Set
|
|
|
- .of(JWSAlgorithm.RS256);
|
|
|
-
|
|
|
- private final JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
|
|
|
-
|
|
|
- private final Set<SignatureAlgorithm> signatureAlgorithms = new HashSet<>();
|
|
|
-
|
|
|
- private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer;
|
|
|
-
|
|
|
- private final JWKSource<SecurityContext> jwkSource;
|
|
|
-
|
|
|
- private JwkSourceJwtDecoderBuilder(JWKSource<SecurityContext> jwkSource) {
|
|
|
- Assert.notNull(jwkSource, "jwkSource cannot be null");
|
|
|
- this.jwkSource = jwkSource;
|
|
|
- this.jwtProcessorCustomizer = (processor) -> {
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Append the given signing
|
|
|
- * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
|
|
|
- * "_blank">algorithm</a> to the set of algorithms to use.
|
|
|
- * @param signatureAlgorithm the algorithm to use
|
|
|
- * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
- */
|
|
|
- public JwkSourceJwtDecoderBuilder jwsAlgorithm(SignatureAlgorithm signatureAlgorithm) {
|
|
|
- Assert.notNull(signatureAlgorithm, "signatureAlgorithm cannot be null");
|
|
|
- this.signatureAlgorithms.add(signatureAlgorithm);
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Configure the list of
|
|
|
- * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
|
|
|
- * "_blank">algorithms</a> to use with the given {@link Consumer}.
|
|
|
- * @param signatureAlgorithmsConsumer a {@link Consumer} for further configuring
|
|
|
- * the algorithm list
|
|
|
- * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
- */
|
|
|
- public JwkSourceJwtDecoderBuilder jwsAlgorithms(Consumer<Set<SignatureAlgorithm>> signatureAlgorithmsConsumer) {
|
|
|
- Assert.notNull(signatureAlgorithmsConsumer, "signatureAlgorithmsConsumer cannot be null");
|
|
|
- signatureAlgorithmsConsumer.accept(this.signatureAlgorithms);
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Use the given {@link Consumer} to customize the {@link JWTProcessor
|
|
|
- * ConfigurableJWTProcessor} before passing it to the build
|
|
|
- * {@link NimbusJwtDecoder}.
|
|
|
- * @param jwtProcessorCustomizer the callback used to alter the processor
|
|
|
- * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
- * @since 5.4
|
|
|
- */
|
|
|
- public JwkSourceJwtDecoderBuilder jwtProcessorCustomizer(
|
|
|
- Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer) {
|
|
|
- Assert.notNull(jwtProcessorCustomizer, "jwtProcessorCustomizer cannot be null");
|
|
|
- this.jwtProcessorCustomizer = jwtProcessorCustomizer;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- JWSKeySelector<SecurityContext> jwsKeySelector(JWKSource<SecurityContext> jwkSource) {
|
|
|
- if (this.signatureAlgorithms.isEmpty()) {
|
|
|
- return new JWSVerificationKeySelector<>(this.defaultAlgorithms.apply(jwkSource), jwkSource);
|
|
|
- }
|
|
|
- Set<JWSAlgorithm> jwsAlgorithms = new HashSet<>();
|
|
|
- for (SignatureAlgorithm signatureAlgorithm : this.signatureAlgorithms) {
|
|
|
- JWSAlgorithm jwsAlgorithm = JWSAlgorithm.parse(signatureAlgorithm.getName());
|
|
|
- jwsAlgorithms.add(jwsAlgorithm);
|
|
|
- }
|
|
|
- return new JWSVerificationKeySelector<>(jwsAlgorithms, jwkSource);
|
|
|
- }
|
|
|
-
|
|
|
- JWTProcessor<SecurityContext> processor() {
|
|
|
- ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
- jwtProcessor.setJWSTypeVerifier(this.typeVerifier);
|
|
|
- jwtProcessor.setJWSKeySelector(jwsKeySelector(this.jwkSource));
|
|
|
- // Spring Security validates the claim set independent from Nimbus
|
|
|
- jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
|
|
|
- });
|
|
|
- this.jwtProcessorCustomizer.accept(jwtProcessor);
|
|
|
- return jwtProcessor;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Build the configured {@link NimbusJwtDecoder}.
|
|
|
- * @return the configured {@link NimbusJwtDecoder}
|
|
|
- */
|
|
|
- public NimbusJwtDecoder build() {
|
|
|
- return new NimbusJwtDecoder(processor());
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* A builder for creating {@link NimbusJwtDecoder} instances based on a public key.
|
|
|
*/
|
|
@@ -903,4 +801,108 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * A builder for creating {@link NimbusJwtDecoder} instances based on a
|
|
|
+ * {@code JWKSource}.
|
|
|
+ *
|
|
|
+ * @since 7.0
|
|
|
+ */
|
|
|
+ public static final class JwkSourceJwtDecoderBuilder {
|
|
|
+
|
|
|
+ private static final JOSEObjectTypeVerifier<SecurityContext> NO_TYPE_VERIFIER = (header, context) -> {
|
|
|
+ };
|
|
|
+
|
|
|
+ private final Function<JWKSource<SecurityContext>, Set<JWSAlgorithm>> defaultAlgorithms = (source) -> Set
|
|
|
+ .of(JWSAlgorithm.RS256);
|
|
|
+
|
|
|
+ private final JOSEObjectTypeVerifier<SecurityContext> typeVerifier = NO_TYPE_VERIFIER;
|
|
|
+
|
|
|
+ private final Set<SignatureAlgorithm> signatureAlgorithms = new HashSet<>();
|
|
|
+
|
|
|
+ private Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer;
|
|
|
+
|
|
|
+ private final JWKSource<SecurityContext> jwkSource;
|
|
|
+
|
|
|
+ private JwkSourceJwtDecoderBuilder(JWKSource<SecurityContext> jwkSource) {
|
|
|
+ Assert.notNull(jwkSource, "jwkSource cannot be null");
|
|
|
+ this.jwkSource = jwkSource;
|
|
|
+ this.jwtProcessorCustomizer = (processor) -> {
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Append the given signing
|
|
|
+ * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
|
|
|
+ * "_blank">algorithm</a> to the set of algorithms to use.
|
|
|
+ * @param signatureAlgorithm the algorithm to use
|
|
|
+ * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
+ */
|
|
|
+ public JwkSourceJwtDecoderBuilder jwsAlgorithm(SignatureAlgorithm signatureAlgorithm) {
|
|
|
+ Assert.notNull(signatureAlgorithm, "signatureAlgorithm cannot be null");
|
|
|
+ this.signatureAlgorithms.add(signatureAlgorithm);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Configure the list of
|
|
|
+ * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
|
|
|
+ * "_blank">algorithms</a> to use with the given {@link Consumer}.
|
|
|
+ * @param signatureAlgorithmsConsumer a {@link Consumer} for further configuring
|
|
|
+ * the algorithm list
|
|
|
+ * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
+ */
|
|
|
+ public JwkSourceJwtDecoderBuilder jwsAlgorithms(Consumer<Set<SignatureAlgorithm>> signatureAlgorithmsConsumer) {
|
|
|
+ Assert.notNull(signatureAlgorithmsConsumer, "signatureAlgorithmsConsumer cannot be null");
|
|
|
+ signatureAlgorithmsConsumer.accept(this.signatureAlgorithms);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Use the given {@link Consumer} to customize the {@link JWTProcessor
|
|
|
+ * ConfigurableJWTProcessor} before passing it to the build
|
|
|
+ * {@link NimbusJwtDecoder}.
|
|
|
+ * @param jwtProcessorCustomizer the callback used to alter the processor
|
|
|
+ * @return a {@link JwkSourceJwtDecoderBuilder } for further configurations
|
|
|
+ * @since 5.4
|
|
|
+ */
|
|
|
+ public JwkSourceJwtDecoderBuilder jwtProcessorCustomizer(
|
|
|
+ Consumer<ConfigurableJWTProcessor<SecurityContext>> jwtProcessorCustomizer) {
|
|
|
+ Assert.notNull(jwtProcessorCustomizer, "jwtProcessorCustomizer cannot be null");
|
|
|
+ this.jwtProcessorCustomizer = jwtProcessorCustomizer;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ JWSKeySelector<SecurityContext> jwsKeySelector(JWKSource<SecurityContext> jwkSource) {
|
|
|
+ if (this.signatureAlgorithms.isEmpty()) {
|
|
|
+ return new JWSVerificationKeySelector<>(this.defaultAlgorithms.apply(jwkSource), jwkSource);
|
|
|
+ }
|
|
|
+ Set<JWSAlgorithm> jwsAlgorithms = new HashSet<>();
|
|
|
+ for (SignatureAlgorithm signatureAlgorithm : this.signatureAlgorithms) {
|
|
|
+ JWSAlgorithm jwsAlgorithm = JWSAlgorithm.parse(signatureAlgorithm.getName());
|
|
|
+ jwsAlgorithms.add(jwsAlgorithm);
|
|
|
+ }
|
|
|
+ return new JWSVerificationKeySelector<>(jwsAlgorithms, jwkSource);
|
|
|
+ }
|
|
|
+
|
|
|
+ JWTProcessor<SecurityContext> processor() {
|
|
|
+ ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
+ jwtProcessor.setJWSTypeVerifier(this.typeVerifier);
|
|
|
+ jwtProcessor.setJWSKeySelector(jwsKeySelector(this.jwkSource));
|
|
|
+ // Spring Security validates the claim set independent from Nimbus
|
|
|
+ jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
|
|
|
+ });
|
|
|
+ this.jwtProcessorCustomizer.accept(jwtProcessor);
|
|
|
+ return jwtProcessor;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Build the configured {@link NimbusJwtDecoder}.
|
|
|
+ * @return the configured {@link NimbusJwtDecoder}
|
|
|
+ */
|
|
|
+ public NimbusJwtDecoder build() {
|
|
|
+ return new NimbusJwtDecoder(processor());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|