@@ -264,11 +264,12 @@ public static SecretKeyJwtDecoderBuilder withSecretKey(SecretKey secretKey) {
264
264
/**
265
265
* Use the given <a href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a>
266
266
* uri.
267
- * @param jwkSetUri the JWK Set uri to use
267
+ * @param jwkSource the JWK Set uri to use
268
268
* @return a {@link JwkSetUriJwtDecoderBuilder} for further configurations
269
+ * @since 7.0
269
270
*/
270
- public static JwkSetUriJwtDecoderBuilder withJwkSource (JWKSource <SecurityContext > jwkSetUri ) {
271
- return new JwkSetUriJwtDecoderBuilder ( jwkSetUri );
271
+ public static JwkSourceJwtDecoderBuilder withJwkSource (JWKSource <SecurityContext > jwkSource ) {
272
+ return new JwkSourceJwtDecoderBuilder ( jwkSource );
272
273
}
273
274
274
275
/**
@@ -813,4 +814,105 @@ JWTProcessor<SecurityContext> processor() {
813
814
814
815
}
815
816
817
+ /**
818
+ * A builder for creating {@link NimbusJwtDecoder} instances based on a
819
+ * <a target="_blank" href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a>
820
+ * uri.
821
+ *
822
+ * @since 7.0
823
+ */
824
+ public static final class JwkSourceJwtDecoderBuilder {
825
+
826
+ private Set <JWSAlgorithm > defaultAlgorithms = Set .of (JWSAlgorithm .RS256 );
827
+
828
+ private final Set <SignatureAlgorithm > signatureAlgorithms = new HashSet <>();
829
+
830
+ private final JWKSource <SecurityContext > jwkSource ;
831
+
832
+ private Consumer <ConfigurableJWTProcessor <SecurityContext >> jwtProcessorCustomizer ;
833
+
834
+ private JwkSourceJwtDecoderBuilder (JWKSource <SecurityContext > jwkSource ) {
835
+ Assert .notNull (jwkSource , "jwkSource cannot be null" );
836
+ this .jwkSource = jwkSource ;
837
+ this .jwtProcessorCustomizer = (processor ) -> {
838
+ };
839
+ }
840
+
841
+ /**
842
+ * Append the given signing
843
+ * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
844
+ * "_blank">algorithm</a> to the set of algorithms to use.
845
+ * @param signatureAlgorithm the algorithm to use
846
+ * @return a {@link JwkSetUriJwtDecoderBuilder} for further configurations
847
+ */
848
+ public JwkSourceJwtDecoderBuilder jwsAlgorithm (SignatureAlgorithm signatureAlgorithm ) {
849
+ Assert .notNull (signatureAlgorithm , "signatureAlgorithm cannot be null" );
850
+ this .signatureAlgorithms .add (signatureAlgorithm );
851
+ return this ;
852
+ }
853
+
854
+ /**
855
+ * Configure the list of
856
+ * <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1" target=
857
+ * "_blank">algorithms</a> to use with the given {@link Consumer}.
858
+ * @param signatureAlgorithmsConsumer a {@link Consumer} for further configuring
859
+ * the algorithm list
860
+ * @return a {@link JwkSetUriJwtDecoderBuilder} for further configurations
861
+ */
862
+ public JwkSourceJwtDecoderBuilder jwsAlgorithms (Consumer <Set <SignatureAlgorithm >> signatureAlgorithmsConsumer ) {
863
+ Assert .notNull (signatureAlgorithmsConsumer , "signatureAlgorithmsConsumer cannot be null" );
864
+ signatureAlgorithmsConsumer .accept (this .signatureAlgorithms );
865
+ return this ;
866
+ }
867
+
868
+ /**
869
+ * Use the given {@link Consumer} to customize the {@link JWTProcessor
870
+ * ConfigurableJWTProcessor} before passing it to the build
871
+ * {@link NimbusJwtDecoder}.
872
+ * @param jwtProcessorCustomizer the callback used to alter the processor
873
+ * @return a {@link JwkSetUriJwtDecoderBuilder} for further configurations
874
+ * @since 5.4
875
+ */
876
+ public JwkSourceJwtDecoderBuilder jwtProcessorCustomizer (
877
+ Consumer <ConfigurableJWTProcessor <SecurityContext >> jwtProcessorCustomizer ) {
878
+ Assert .notNull (jwtProcessorCustomizer , "jwtProcessorCustomizer cannot be null" );
879
+ this .jwtProcessorCustomizer = jwtProcessorCustomizer ;
880
+ return this ;
881
+ }
882
+
883
+ JWSKeySelector <SecurityContext > jwsKeySelector () {
884
+ if (this .signatureAlgorithms .isEmpty ()) {
885
+ return new JWSVerificationKeySelector <>(this .defaultAlgorithms , this .jwkSource );
886
+ }
887
+ Set <JWSAlgorithm > jwsAlgorithms = new HashSet <>();
888
+ for (SignatureAlgorithm signatureAlgorithm : this .signatureAlgorithms ) {
889
+ JWSAlgorithm jwsAlgorithm = JWSAlgorithm .parse (signatureAlgorithm .getName ());
890
+ jwsAlgorithms .add (jwsAlgorithm );
891
+ }
892
+ return new JWSVerificationKeySelector <>(jwsAlgorithms , this .jwkSource );
893
+ }
894
+
895
+ /**
896
+ * Build the configured {@link NimbusJwtDecoder}.
897
+ * @return the configured {@link NimbusJwtDecoder}
898
+ */
899
+ public NimbusJwtDecoder build () {
900
+ return new NimbusJwtDecoder (processor ());
901
+ }
902
+
903
+ JWTProcessor <SecurityContext > processor () {
904
+ ConfigurableJWTProcessor <SecurityContext > jwtProcessor = new DefaultJWTProcessor <>();
905
+ // Spring Security validates the claim set independent from Nimbus
906
+ jwtProcessor .setJWSTypeVerifier ((header , context ) -> {
907
+ });
908
+ jwtProcessor .setJWSKeySelector (jwsKeySelector ());
909
+ // Spring Security validates the claim set independent from Nimbus
910
+ jwtProcessor .setJWTClaimsSetVerifier ((claims , context ) -> {
911
+ });
912
+ this .jwtProcessorCustomizer .accept (jwtProcessor );
913
+ return jwtProcessor ;
914
+ }
915
+
916
+ }
917
+
816
918
}
0 commit comments