diff --git a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java
index 05b259d0a6..2bef540d08 100644
--- a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java
+++ b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java
@@ -262,6 +262,35 @@ public final class SecurityMockMvcRequestPostProcessors {
return new JwtRequestPostProcessor(jwtBuilder.build());
}
+ /**
+ * Establish a {@link SecurityContext} that has a
+ * {@link JwtAuthenticationToken} for the
+ * {@link Authentication} and a {@link Jwt} for the
+ * {@link Authentication#getPrincipal()}. All details are
+ * declarative and do not require the JWT to be valid.
+ *
+ *
+ * The support works by associating the authentication to the HttpServletRequest. To associate
+ * the request to the SecurityContextHolder you need to ensure that the
+ * SecurityContextPersistenceFilter is associated with the MockMvc instance. A few
+ * ways to do this are:
+ *
+ *
+ *
+ * - Invoking apply {@link SecurityMockMvcConfigurers#springSecurity()}
+ * - Adding Spring Security's FilterChainProxy to MockMvc
+ * - Manually adding {@link SecurityContextPersistenceFilter} to the MockMvc
+ * instance may make sense when using MockMvcBuilders standaloneSetup
+ *
+ *
+ * @param jwt The preliminary constructed {@link Jwt}
+ * @return the {@link JwtRequestPostProcessor} for additional customization
+ * @since 5.2
+ */
+ public static JwtRequestPostProcessor jwt(Jwt jwt) {
+ return new JwtRequestPostProcessor(jwt);
+ }
+
/**
* Establish a {@link SecurityContext} that uses the specified {@link Authentication}
* for the {@link Authentication#getPrincipal()} and a custom {@link UserDetails}. All
diff --git a/test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java b/test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java
index 565de65bc0..97d4a5aee1 100644
--- a/test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java
+++ b/test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java
@@ -15,8 +15,13 @@
*/
package org.springframework.security.test.web.servlet.request;
-import java.util.Arrays;
+import java.time.Instant;
import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+import java.util.Collections;
+
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
@@ -34,6 +39,8 @@ import org.springframework.security.config.BeanIds;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
+import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
@@ -154,4 +161,22 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
assertThat((List) context.getAuthentication().getAuthorities())
.containsOnly(this.authority1);
}
+
+ @Test
+ public void jwtWhenProvidingPreparedJwtThenUsesItForAuthentication() {
+ Map claims = new HashMap<>();
+ claims.put(IdTokenClaimNames.SUB, "some_user");
+ Jwt originalToken = new Jwt("token123", Instant.now(), Instant.now().plusSeconds(3600),
+ Collections.singletonMap("header1", "value1"), claims);
+ jwt(originalToken).postProcessRequest(this.request);
+
+
+ verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
+ any(HttpServletResponse.class));
+ SecurityContext context = this.contextCaptor.getValue();
+ JwtAuthenticationToken retrievedToken = (JwtAuthenticationToken) context.getAuthentication();
+ assertThat(retrievedToken.getToken().getSubject()).isEqualTo("some_user");
+ assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token123");
+ assertThat(retrievedToken.getToken().getHeaders().get("header1")).isEqualTo("value1");
+ }
}