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 .core .AuthenticationException ;
4140import org .springframework .security .oauth2 .core .OAuth2AuthenticationException ;
4241import org .springframework .security .oauth2 .jose .TestKeys ;
42+ import org .springframework .security .oauth2 .jwt .Jwt ;
4343import 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 ;
4447import org .springframework .security .oauth2 .server .resource .InvalidBearerTokenException ;
45- import org .springframework .security .oauth2 .server .resource .authentication .JwtIssuerAuthenticationManagerResolver .TrustedIssuerJwtAuthenticationManagerResolver ;
4648
4749import static org .assertj .core .api .Assertions .assertThat ;
4850import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
5153import static org .mockito .BDDMockito .given ;
5254import static org .mockito .BDDMockito .mock ;
5355import static org .mockito .BDDMockito .verify ;
56+ import static org .mockito .Mockito .mockStatic ;
5457
5558/**
5659 * Tests for {@link JwtIssuerAuthenticationManagerResolver}
5760 */
5861public class JwtIssuerAuthenticationManagerResolverTests {
5962
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-
6563 private String jwt = jwt ("iss" , "trusted" );
6664
6765 private String evil = jwt ("iss" , "\" " );
@@ -70,120 +68,50 @@ public class JwtIssuerAuthenticationManagerResolverTests {
7068
7169 @ Test
7270 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 );
9887 Authentication authentication = authenticationManager .authenticate (token );
9988 assertThat (authentication .isAuthenticated ()).isTrue ();
10089 }
10190 }
10291
10392 @ Test
10493 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" ;
13495
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 );
160108 AuthenticationManager authenticationManager = authenticationManagerResolver .resolve (null );
161109 assertThat (authenticationManager ).isNotNull ();
162- assertThatExceptionOfType (IllegalArgumentException .class )
163- .isThrownBy (() -> authenticationManager .authenticate (token ));
164110 Authentication authentication = authenticationManager .authenticate (token );
165111 assertThat (authentication .isAuthenticated ()).isTrue ();
166112 }
167113 }
168114
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-
187115 @ Test
188116 public void resolveWhenUsingUntrustedIssuerThenException () {
189117 JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerAuthenticationManagerResolver
0 commit comments