Skip to content

Commit 9323d8e

Browse files
sandmannnjzheaux
authored andcommitted
Extended testing api for JWT
Added new implementation of jwt() method that makes it possible to directly provide a previously prepared JWT token to the MockMvc request builder. Issue: gh-6896
1 parent 78cde52 commit 9323d8e

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,35 @@ public static JwtRequestPostProcessor jwt(Consumer<Jwt.Builder> jwtBuilderConsum
262262
return new JwtRequestPostProcessor(jwtBuilder.build());
263263
}
264264

265+
/**
266+
* Establish a {@link SecurityContext} that has a
267+
* {@link JwtAuthenticationToken} for the
268+
* {@link Authentication} and a {@link Jwt} for the
269+
* {@link Authentication#getPrincipal()}. All details are
270+
* declarative and do not require the JWT to be valid.
271+
*
272+
* <p>
273+
* The support works by associating the authentication to the HttpServletRequest. To associate
274+
* the request to the SecurityContextHolder you need to ensure that the
275+
* SecurityContextPersistenceFilter is associated with the MockMvc instance. A few
276+
* ways to do this are:
277+
* </p>
278+
*
279+
* <ul>
280+
* <li>Invoking apply {@link SecurityMockMvcConfigurers#springSecurity()}</li>
281+
* <li>Adding Spring Security's FilterChainProxy to MockMvc</li>
282+
* <li>Manually adding {@link SecurityContextPersistenceFilter} to the MockMvc
283+
* instance may make sense when using MockMvcBuilders standaloneSetup</li>
284+
* </ul>
285+
*
286+
* @param jwt The preliminary constructed {@link Jwt}
287+
* @return the {@link JwtRequestPostProcessor} for additional customization
288+
* @since 5.2
289+
*/
290+
public static JwtRequestPostProcessor jwt(Jwt jwt) {
291+
return new JwtRequestPostProcessor(jwt);
292+
}
293+
265294
/**
266295
* Establish a {@link SecurityContext} that uses the specified {@link Authentication}
267296
* for the {@link Authentication#getPrincipal()} and a custom {@link UserDetails}. All

test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@
1515
*/
1616
package org.springframework.security.test.web.servlet.request;
1717

18-
import java.util.Arrays;
18+
import java.time.Instant;
1919
import java.util.List;
20+
import java.util.Map;
21+
import java.util.HashMap;
22+
import java.util.Arrays;
23+
import java.util.Collections;
24+
2025
import javax.servlet.http.HttpServletResponse;
2126

2227
import org.junit.After;
@@ -34,6 +39,8 @@
3439
import org.springframework.security.core.GrantedAuthority;
3540
import org.springframework.security.core.authority.SimpleGrantedAuthority;
3641
import org.springframework.security.core.context.SecurityContext;
42+
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
43+
import org.springframework.security.oauth2.jwt.Jwt;
3744
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
3845
import org.springframework.security.test.context.TestSecurityContextHolder;
3946
import org.springframework.security.test.web.support.WebTestUtils;
@@ -154,4 +161,22 @@ public void jwtWhenProvidingGrantedAuthoritiesThenProducesJwtAuthentication() {
154161
assertThat((List<GrantedAuthority>) context.getAuthentication().getAuthorities())
155162
.containsOnly(this.authority1);
156163
}
164+
165+
@Test
166+
public void jwtWhenProvidingPreparedJwtThenUsesItForAuthentication() {
167+
Map<String, Object> claims = new HashMap<>();
168+
claims.put(IdTokenClaimNames.SUB, "some_user");
169+
Jwt originalToken = new Jwt("token123", Instant.now(), Instant.now().plusSeconds(3600),
170+
Collections.singletonMap("header1", "value1"), claims);
171+
jwt(originalToken).postProcessRequest(this.request);
172+
173+
174+
verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
175+
any(HttpServletResponse.class));
176+
SecurityContext context = this.contextCaptor.getValue();
177+
JwtAuthenticationToken retrievedToken = (JwtAuthenticationToken) context.getAuthentication();
178+
assertThat(retrievedToken.getToken().getSubject()).isEqualTo("some_user");
179+
assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token123");
180+
assertThat(retrievedToken.getToken().getHeaders().get("header1")).isEqualTo("value1");
181+
}
157182
}

0 commit comments

Comments
 (0)