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