19
19
import java .security .KeyFactory ;
20
20
import java .security .interfaces .RSAPublicKey ;
21
21
import java .security .spec .X509EncodedKeySpec ;
22
+ import java .util .ArrayList ;
22
23
import java .util .Base64 ;
24
+ import java .util .Collections ;
25
+ import java .util .List ;
26
+ import java .util .function .Supplier ;
23
27
24
28
import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
25
29
import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
32
36
import org .springframework .context .annotation .Configuration ;
33
37
import org .springframework .security .config .web .server .ServerHttpSecurity ;
34
38
import org .springframework .security .config .web .server .ServerHttpSecurity .OAuth2ResourceServerSpec ;
39
+ import org .springframework .security .oauth2 .core .DelegatingOAuth2TokenValidator ;
40
+ import org .springframework .security .oauth2 .core .OAuth2TokenValidator ;
35
41
import 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 ;
36
45
import org .springframework .security .oauth2 .jwt .JwtValidators ;
37
46
import org .springframework .security .oauth2 .jwt .NimbusReactiveJwtDecoder ;
38
47
import org .springframework .security .oauth2 .jwt .ReactiveJwtDecoder ;
39
48
import org .springframework .security .oauth2 .jwt .ReactiveJwtDecoders ;
40
49
import org .springframework .security .oauth2 .jwt .SupplierReactiveJwtDecoder ;
41
50
import org .springframework .security .web .server .SecurityWebFilterChain ;
51
+ import org .springframework .util .CollectionUtils ;
42
52
43
53
/**
44
54
* Configures a {@link ReactiveJwtDecoder} when a JWK Set URI, OpenID Connect Issuer URI
49
59
* @author Artsiom Yudovin
50
60
* @author HaiTao Zhang
51
61
* @author Anastasiia Losieva
62
+ * @author Mushtaq Ahmed
52
63
*/
53
64
@ Configuration (proxyBeanMethods = false )
54
65
class ReactiveOAuth2ResourceServerJwkConfiguration {
@@ -70,19 +81,34 @@ ReactiveJwtDecoder jwtDecoder() {
70
81
.withJwkSetUri (this .properties .getJwkSetUri ())
71
82
.jwsAlgorithm (SignatureAlgorithm .from (this .properties .getJwsAlgorithm ())).build ();
72
83
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 ));
76
87
return nimbusReactiveJwtDecoder ;
77
88
}
78
89
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
+
79
103
@ Bean
80
104
@ Conditional (KeyValueCondition .class )
81
105
NimbusReactiveJwtDecoder jwtDecoderByPublicKeyValue () throws Exception {
82
106
RSAPublicKey publicKey = (RSAPublicKey ) KeyFactory .getInstance ("RSA" )
83
107
.generatePublic (new X509EncodedKeySpec (getKeySpec (this .properties .readPublicKey ())));
84
- return NimbusReactiveJwtDecoder .withPublicKey (publicKey )
108
+ NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder .withPublicKey (publicKey )
85
109
.signatureAlgorithm (SignatureAlgorithm .from (this .properties .getJwsAlgorithm ())).build ();
110
+ jwtDecoder .setJwtValidator (getValidators (JwtValidators ::createDefault ));
111
+ return jwtDecoder ;
86
112
}
87
113
88
114
private byte [] getKeySpec (String keyValue ) {
@@ -93,8 +119,13 @@ private byte[] getKeySpec(String keyValue) {
93
119
@ Bean
94
120
@ Conditional (IssuerUriCondition .class )
95
121
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
+ });
98
129
}
99
130
100
131
}
0 commit comments