30
30
import com .nimbusds .jwt .JWTClaimsSet ;
31
31
import com .nimbusds .jwt .PlainJWT ;
32
32
import net .minidev .json .JSONObject ;
33
- import okhttp3 .mockwebserver .MockResponse ;
34
- import okhttp3 .mockwebserver .MockWebServer ;
35
33
import org .junit .jupiter .api .Test ;
34
+ import org .mockito .MockedStatic ;
36
35
37
36
import org .springframework .security .authentication .AuthenticationManager ;
38
37
import org .springframework .security .authentication .AuthenticationManagerResolver ;
39
38
import org .springframework .security .core .Authentication ;
40
39
import org .springframework .security .oauth2 .core .OAuth2AuthenticationException ;
41
40
import org .springframework .security .oauth2 .jose .TestKeys ;
41
+ import org .springframework .security .oauth2 .jwt .Jwt ;
42
42
import org .springframework .security .oauth2 .jwt .JwtClaimNames ;
43
- import org .springframework .security .oauth2 .server .resource .authentication .JwtIssuerAuthenticationManagerResolver .TrustedIssuerJwtAuthenticationManagerResolver ;
43
+ import org .springframework .security .oauth2 .jwt .JwtDecoder ;
44
+ import org .springframework .security .oauth2 .jwt .JwtDecoders ;
45
+ import org .springframework .security .oauth2 .jwt .TestJwts ;
44
46
45
47
import static org .assertj .core .api .Assertions .assertThat ;
46
48
import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
47
49
import static org .assertj .core .api .Assertions .assertThatIllegalArgumentException ;
50
+ import static org .mockito .BDDMockito .given ;
48
51
import static org .mockito .BDDMockito .mock ;
49
52
import static org .mockito .BDDMockito .verify ;
53
+ import static org .mockito .Mockito .mockStatic ;
50
54
51
55
/**
52
56
* Tests for {@link JwtIssuerAuthenticationManagerResolver}
53
57
*/
54
58
public class JwtIssuerAuthenticationManagerResolverTests {
55
59
56
- private static final String DEFAULT_RESPONSE_TEMPLATE = "{\n " + " \" issuer\" : \" %s\" , \n "
57
- + " \" jwks_uri\" : \" %s/.well-known/jwks.json\" \n " + "}" ;
58
-
59
- private static final String JWK_SET = "{\" keys\" :[{\" kty\" :\" RSA\" ,\" e\" :\" AQAB\" ,\" use\" :\" sig\" ,\" kid\" :\" one\" ,\" n\" :\" 3FlqJr5TRskIQIgdE3Dd7D9lboWdcTUT8a-fJR7MAvQm7XXNoYkm3v7MQL1NYtDvL2l8CAnc0WdSTINU6IRvc5Kqo2Q4csNX9SHOmEfzoROjQqahEcve1jBXluoCXdYuYpx4_1tfRgG6ii4Uhxh6iI8qNMJQX-fLfqhbfYfxBQVRPywBkAbIP4x1EAsbC6FSNmkhCxiMNqEgxaIpY8C2kJdJ_ZIV-WW4noDdzpKqHcwmB8FsrumlVY_DNVvUSDIipiq9PbP4H99TXN1o746oRaNa07rq1hoCgMSSy-85SagCoxlmyE-D-of9SsMY8Ol9t0rdzpobBuhyJ_o5dfvjKw\" }]}" ;
60
-
61
60
private String jwt = jwt ("iss" , "trusted" );
62
61
63
62
private String evil = jwt ("iss" , "\" " );
@@ -66,120 +65,50 @@ public class JwtIssuerAuthenticationManagerResolverTests {
66
65
67
66
@ Test
68
67
public void resolveWhenUsingFromTrustedIssuersThenReturnsAuthenticationManager () throws Exception {
69
- try (MockWebServer server = new MockWebServer ()) {
70
- server .start ();
71
- String issuer = server .url ("" ).toString ();
72
- // @formatter:off
73
- server .enqueue (new MockResponse ().setResponseCode (200 )
74
- .setHeader ("Content-Type" , "application/json" )
75
- .setBody (String .format (DEFAULT_RESPONSE_TEMPLATE , issuer , issuer )
76
- ));
77
- server .enqueue (new MockResponse ().setResponseCode (200 )
78
- .setHeader ("Content-Type" , "application/json" )
79
- .setBody (JWK_SET )
80
- );
81
- server .enqueue (new MockResponse ().setResponseCode (200 )
82
- .setHeader ("Content-Type" , "application/json" )
83
- .setBody (JWK_SET )
84
- );
85
- // @formatter:on
86
- JWSObject jws = new JWSObject (new JWSHeader (JWSAlgorithm .RS256 ),
87
- new Payload (new JSONObject (Collections .singletonMap (JwtClaimNames .ISS , issuer ))));
88
- jws .sign (new RSASSASigner (TestKeys .DEFAULT_PRIVATE_KEY ));
89
- JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
90
- .fromTrustedIssuers (issuer );
91
- Authentication token = withBearerToken (jws .serialize ());
92
- AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
93
- assertThat (authenticationManager ).isNotNull ();
68
+ String issuer = "https://idp.example" ;
69
+
70
+ // @formatter:on
71
+ JWSObject jws = new JWSObject (new JWSHeader (JWSAlgorithm .RS256 ),
72
+ new Payload (new JSONObject (Collections .singletonMap (JwtClaimNames .ISS , issuer ))));
73
+ jws .sign (new RSASSASigner (TestKeys .DEFAULT_PRIVATE_KEY ));
74
+ JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
75
+ .fromTrustedIssuers (issuer );
76
+ Authentication token = withBearerToken (jws .serialize ());
77
+ AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
78
+ assertThat (authenticationManager ).isNotNull ();
79
+ JwtDecoder decoder = mock (JwtDecoder .class );
80
+ Jwt jwt = TestJwts .user ();
81
+ given (decoder .decode (token .getName ())).willReturn (jwt );
82
+ try (MockedStatic <JwtDecoders > jwtDecoders = mockStatic (JwtDecoders .class )) {
83
+ given (JwtDecoders .fromIssuerLocation (issuer )).willReturn (decoder );
94
84
Authentication authentication = authenticationManager .authenticate (token );
95
85
assertThat (authentication .isAuthenticated ()).isTrue ();
96
86
}
97
87
}
98
88
99
89
@ Test
100
90
public void resolveWhenUsingFromTrustedIssuersPredicateThenReturnsAuthenticationManager () throws Exception {
101
- try (MockWebServer server = new MockWebServer ()) {
102
- server .start ();
103
- String issuer = server .url ("" ).toString ();
104
- // @formatter:off
105
- server .enqueue (new MockResponse ().setResponseCode (200 )
106
- .setHeader ("Content-Type" , "application/json" )
107
- .setBody (String .format (DEFAULT_RESPONSE_TEMPLATE , issuer , issuer )
108
- ));
109
- server .enqueue (new MockResponse ().setResponseCode (200 )
110
- .setHeader ("Content-Type" , "application/json" )
111
- .setBody (JWK_SET )
112
- );
113
- server .enqueue (new MockResponse ().setResponseCode (200 )
114
- .setHeader ("Content-Type" , "application/json" )
115
- .setBody (JWK_SET )
116
- );
117
- // @formatter:on
118
- JWSObject jws = new JWSObject (new JWSHeader (JWSAlgorithm .RS256 ),
119
- new Payload (new JSONObject (Collections .singletonMap (JwtClaimNames .ISS , issuer ))));
120
- jws .sign (new RSASSASigner (TestKeys .DEFAULT_PRIVATE_KEY ));
121
- JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
122
- .fromTrustedIssuers (issuer ::equals );
123
- Authentication token = withBearerToken (jws .serialize ());
124
- AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
125
- assertThat (authenticationManager ).isNotNull ();
126
- Authentication authentication = authenticationManager .authenticate (token );
127
- assertThat (authentication .isAuthenticated ()).isTrue ();
128
- }
129
- }
91
+ String issuer = "https://idp.example" ;
130
92
131
- @ Test
132
- public void resolveWhednUsingTrustedIssuerThenReturnsAuthenticationManager () throws Exception {
133
- try (MockWebServer server = new MockWebServer ()) {
134
- server .start ();
135
- String issuer = server .url ("" ).toString ();
136
- // @formatter:off
137
- server .enqueue (new MockResponse ().setResponseCode (500 )
138
- .setHeader ("Content-Type" , "application/json" )
139
- .setBody (String .format (DEFAULT_RESPONSE_TEMPLATE , issuer , issuer ))
140
- );
141
- server .enqueue (new MockResponse ().setResponseCode (200 )
142
- .setHeader ("Content-Type" , "application/json" )
143
- .setBody (String .format (DEFAULT_RESPONSE_TEMPLATE , issuer , issuer ))
144
- );
145
- server .enqueue (new MockResponse ().setResponseCode (200 )
146
- .setHeader ("Content-Type" , "application/json" )
147
- .setBody (JWK_SET )
148
- );
149
- // @formatter:on
150
- JWSObject jws = new JWSObject (new JWSHeader (JWSAlgorithm .RS256 ),
151
- new Payload (new JSONObject (Collections .singletonMap (JwtClaimNames .ISS , issuer ))));
152
- jws .sign (new RSASSASigner (TestKeys .DEFAULT_PRIVATE_KEY ));
153
- JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
154
- .fromTrustedIssuers (issuer );
155
- Authentication token = withBearerToken (jws .serialize ());
93
+ // @formatter:on
94
+ JWSObject jws = new JWSObject (new JWSHeader (JWSAlgorithm .RS256 ),
95
+ new Payload (new JSONObject (Collections .singletonMap (JwtClaimNames .ISS , issuer ))));
96
+ jws .sign (new RSASSASigner (TestKeys .DEFAULT_PRIVATE_KEY ));
97
+ JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
98
+ .fromTrustedIssuers (issuer ::equals );
99
+ Authentication token = withBearerToken (jws .serialize ());
100
+ JwtDecoder decoder = mock (JwtDecoder .class );
101
+ Jwt jwt = TestJwts .user ();
102
+ given (decoder .decode (token .getName ())).willReturn (jwt );
103
+ try (MockedStatic <JwtDecoders > jwtDecoders = mockStatic (JwtDecoders .class )) {
104
+ given (JwtDecoders .fromIssuerLocation (issuer )).willReturn (decoder );
156
105
AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
157
106
assertThat (authenticationManager ).isNotNull ();
158
- assertThatExceptionOfType (IllegalArgumentException .class )
159
- .isThrownBy (() -> authenticationManager .authenticate (token ));
160
107
Authentication authentication = authenticationManager .authenticate (token );
161
108
assertThat (authentication .isAuthenticated ()).isTrue ();
162
109
}
163
110
}
164
111
165
- @ Test
166
- public void resolveWhenUsingSameIssuerThenReturnsSameAuthenticationManager () throws Exception {
167
- try (MockWebServer server = new MockWebServer ()) {
168
- String issuer = server .url ("" ).toString ();
169
- server .enqueue (new MockResponse ().setResponseCode (200 )
170
- .setHeader ("Content-Type" , "application/json" )
171
- .setBody (String .format (DEFAULT_RESPONSE_TEMPLATE , issuer , issuer )));
172
- server .enqueue (new MockResponse ().setResponseCode (200 )
173
- .setHeader ("Content-Type" , "application/json" )
174
- .setBody (JWK_SET ));
175
- TrustedIssuerJwtAuthenticationManagerResolver resolver = new TrustedIssuerJwtAuthenticationManagerResolver (
176
- (iss ) -> iss .equals (issuer ));
177
- AuthenticationManager authenticationManager = resolver .resolve (issuer );
178
- AuthenticationManager cachedAuthenticationManager = resolver .resolve (issuer );
179
- assertThat (authenticationManager ).isSameAs (cachedAuthenticationManager );
180
- }
181
- }
182
-
183
112
@ Test
184
113
public void resolveWhenUsingUntrustedIssuerThenException () {
185
114
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
0 commit comments