3030import com .nimbusds .jwt .JWTClaimsSet ;
3131import com .nimbusds .jwt .PlainJWT ;
3232import net .minidev .json .JSONObject ;
33- import okhttp3 .mockwebserver .MockResponse ;
34- import okhttp3 .mockwebserver .MockWebServer ;
3533import org .junit .jupiter .api .Test ;
34+ import org .mockito .MockedStatic ;
3635
3736import org .springframework .security .authentication .AuthenticationManager ;
3837import org .springframework .security .authentication .AuthenticationManagerResolver ;
3938import org .springframework .security .core .Authentication ;
4039import org .springframework .security .oauth2 .core .OAuth2AuthenticationException ;
4140import org .springframework .security .oauth2 .jose .TestKeys ;
41+ import org .springframework .security .oauth2 .jwt .Jwt ;
4242import 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 ;
4446
4547import static org .assertj .core .api .Assertions .assertThat ;
4648import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
4749import static org .assertj .core .api .Assertions .assertThatIllegalArgumentException ;
50+ import static org .mockito .BDDMockito .given ;
4851import static org .mockito .BDDMockito .mock ;
4952import static org .mockito .BDDMockito .verify ;
53+ import static org .mockito .Mockito .mockStatic ;
5054
5155/**
5256 * Tests for {@link JwtIssuerAuthenticationManagerResolver}
5357 */
5458public class JwtIssuerAuthenticationManagerResolverTests {
5559
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-
6160 private String jwt = jwt ("iss" , "trusted" );
6261
6362 private String evil = jwt ("iss" , "\" " );
@@ -66,120 +65,50 @@ public class JwtIssuerAuthenticationManagerResolverTests {
6665
6766 @ Test
6867 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 );
9484 Authentication authentication = authenticationManager .authenticate (token );
9585 assertThat (authentication .isAuthenticated ()).isTrue ();
9686 }
9787 }
9888
9989 @ Test
10090 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" ;
13092
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 );
156105 AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
157106 assertThat (authenticationManager ).isNotNull ();
158- assertThatExceptionOfType (IllegalArgumentException .class )
159- .isThrownBy (() -> authenticationManager .authenticate (token ));
160107 Authentication authentication = authenticationManager .authenticate (token );
161108 assertThat (authentication .isAuthenticated ()).isTrue ();
162109 }
163110 }
164111
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-
183112 @ Test
184113 public void resolveWhenUsingUntrustedIssuerThenException () {
185114 JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
0 commit comments