1919import java .security .KeyFactory ;
2020import java .security .interfaces .RSAPublicKey ;
2121import java .security .spec .X509EncodedKeySpec ;
22+ import java .util .ArrayList ;
2223import java .util .Base64 ;
24+ import java .util .Collections ;
25+ import java .util .List ;
26+ import java .util .function .Supplier ;
2327
2428import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
2529import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
3236import org .springframework .context .annotation .Configuration ;
3337import org .springframework .security .config .web .server .ServerHttpSecurity ;
3438import org .springframework .security .config .web .server .ServerHttpSecurity .OAuth2ResourceServerSpec ;
39+ import org .springframework .security .oauth2 .core .DelegatingOAuth2TokenValidator ;
40+ import org .springframework .security .oauth2 .core .OAuth2TokenValidator ;
3541import org .springframework .security .oauth2 .jose .jws .SignatureAlgorithm ;
42+ import org .springframework .security .oauth2 .jwt .Jwt ;
43+ import org .springframework .security .oauth2 .jwt .JwtClaimNames ;
44+ import org .springframework .security .oauth2 .jwt .JwtClaimValidator ;
3645import org .springframework .security .oauth2 .jwt .JwtValidators ;
3746import org .springframework .security .oauth2 .jwt .NimbusReactiveJwtDecoder ;
3847import org .springframework .security .oauth2 .jwt .ReactiveJwtDecoder ;
3948import org .springframework .security .oauth2 .jwt .ReactiveJwtDecoders ;
4049import org .springframework .security .oauth2 .jwt .SupplierReactiveJwtDecoder ;
4150import org .springframework .security .web .server .SecurityWebFilterChain ;
51+ import org .springframework .util .CollectionUtils ;
4252
4353/**
4454 * Configures a {@link ReactiveJwtDecoder} when a JWK Set URI, OpenID Connect Issuer URI
4959 * @author Artsiom Yudovin
5060 * @author HaiTao Zhang
5161 * @author Anastasiia Losieva
62+ * @author Mushtaq Ahmed
5263 */
5364@ Configuration (proxyBeanMethods = false )
5465class ReactiveOAuth2ResourceServerJwkConfiguration {
@@ -70,19 +81,34 @@ ReactiveJwtDecoder jwtDecoder() {
7081 .withJwkSetUri (this .properties .getJwkSetUri ())
7182 .jwsAlgorithm (SignatureAlgorithm .from (this .properties .getJwsAlgorithm ())).build ();
7283 String issuerUri = this .properties .getIssuerUri ();
73- if (issuerUri != null ) {
74- nimbusReactiveJwtDecoder . setJwtValidator ( JwtValidators .createDefaultWithIssuer (issuerUri )) ;
75- }
84+ Supplier < OAuth2TokenValidator < Jwt >> defaultValidator = (issuerUri != null )
85+ ? () -> JwtValidators .createDefaultWithIssuer (issuerUri ) : JwtValidators :: createDefault ;
86+ nimbusReactiveJwtDecoder . setJwtValidator ( getValidators ( defaultValidator ));
7687 return nimbusReactiveJwtDecoder ;
7788 }
7889
90+ private OAuth2TokenValidator <Jwt > getValidators (Supplier <OAuth2TokenValidator <Jwt >> defaultValidator ) {
91+ OAuth2TokenValidator <Jwt > defaultValidators = defaultValidator .get ();
92+ List <String > audiences = this .properties .getAudiences ();
93+ if (CollectionUtils .isEmpty (audiences )) {
94+ return defaultValidators ;
95+ }
96+ List <OAuth2TokenValidator <Jwt >> validators = new ArrayList <>();
97+ validators .add (defaultValidators );
98+ validators .add (new JwtClaimValidator <List <String >>(JwtClaimNames .AUD ,
99+ (aud ) -> aud != null && !Collections .disjoint (aud , audiences )));
100+ return new DelegatingOAuth2TokenValidator <>(validators );
101+ }
102+
79103 @ Bean
80104 @ Conditional (KeyValueCondition .class )
81105 NimbusReactiveJwtDecoder jwtDecoderByPublicKeyValue () throws Exception {
82106 RSAPublicKey publicKey = (RSAPublicKey ) KeyFactory .getInstance ("RSA" )
83107 .generatePublic (new X509EncodedKeySpec (getKeySpec (this .properties .readPublicKey ())));
84- return NimbusReactiveJwtDecoder .withPublicKey (publicKey )
108+ NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder .withPublicKey (publicKey )
85109 .signatureAlgorithm (SignatureAlgorithm .from (this .properties .getJwsAlgorithm ())).build ();
110+ jwtDecoder .setJwtValidator (getValidators (JwtValidators ::createDefault ));
111+ return jwtDecoder ;
86112 }
87113
88114 private byte [] getKeySpec (String keyValue ) {
@@ -93,8 +119,13 @@ private byte[] getKeySpec(String keyValue) {
93119 @ Bean
94120 @ Conditional (IssuerUriCondition .class )
95121 SupplierReactiveJwtDecoder jwtDecoderByIssuerUri () {
96- return new SupplierReactiveJwtDecoder (
97- () -> ReactiveJwtDecoders .fromIssuerLocation (this .properties .getIssuerUri ()));
122+ return new SupplierReactiveJwtDecoder (() -> {
123+ NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder ) ReactiveJwtDecoders
124+ .fromIssuerLocation (this .properties .getIssuerUri ());
125+ jwtDecoder .setJwtValidator (
126+ getValidators (() -> JwtValidators .createDefaultWithIssuer (this .properties .getIssuerUri ())));
127+ return jwtDecoder ;
128+ });
98129 }
99130
100131 }
0 commit comments