Isolate Jwt Test Support

Isolating Jwt test support inside JwtRequestPostProcessor and
JwtMutator.

Fixes gh-7641
This commit is contained in:
Josh Cummings 2019-11-22 12:38:01 -07:00
parent 8a95e5798d
commit 7cbd1665a6
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
8 changed files with 107 additions and 136 deletions

View File

@ -203,7 +203,7 @@ Any headers or claims can be configured with their corresponding methods:
[source,java] [source,java]
---- ----
client client
.mutateWith(jwt(jwt -> jwt.header("kid", "one") .mutateWith(mockJwt().jwt(jwt -> jwt.header("kid", "one")
.claim("iss", "https://idp.example.org"))) .claim("iss", "https://idp.example.org")))
.get().uri("/endpoint").exchange(); .get().uri("/endpoint").exchange();
---- ----
@ -211,7 +211,7 @@ client
[source,java] [source,java]
---- ----
client client
.mutateWith(jwt(jwt -> jwt.claims(claims -> claims.remove("scope")))) .mutateWith(mockJwt().jwt(jwt -> jwt.claims(claims -> claims.remove("scope"))))
.get().uri("/endpoint").exchange(); .get().uri("/endpoint").exchange();
---- ----
@ -244,7 +244,7 @@ Jwt jwt = Jwt.withTokenValue("token")
.claim("scope", "read"); .claim("scope", "read");
client client
.mutateWith(jwt(jwt)) .mutateWith(mockJwt().jwt(jwt))
.get().uri("/endpoint").exchange(); .get().uri("/endpoint").exchange();
---- ----

View File

@ -335,14 +335,14 @@ Any headers or claims can be configured with their corresponding methods:
---- ----
mvc mvc
.perform(get("/endpoint") .perform(get("/endpoint")
.with(jwt(jwt -> jwt.header("kid", "one").claim("iss", "https://idp.example.org")))); .with(jwt().jwt(jwt -> jwt.header("kid", "one").claim("iss", "https://idp.example.org"))));
---- ----
[source,java] [source,java]
---- ----
mvc mvc
.perform(get("/endpoint") .perform(get("/endpoint")
.with(jwt(jwt -> jwt.claims(claims -> claims.remove("scope"))))); .with(jwt().jwt(jwt -> jwt.claims(claims -> claims.remove("scope")))));
---- ----
The `scope` and `scp` claims are processed the same way here as they are in a normal bearer token request. The `scope` and `scp` claims are processed the same way here as they are in a normal bearer token request.
@ -375,7 +375,7 @@ Jwt jwt = Jwt.withTokenValue("token")
mvc mvc
.perform(get("/endpoint") .perform(get("/endpoint")
.with(jwt(jwt))); .with(jwt().jwt(jwt)));
---- ----
===== `authentication()` `RequestPostProcessor` ===== `authentication()` `RequestPostProcessor`

View File

@ -50,14 +50,14 @@ public class OAuth2ResourceServerControllerTests {
@Test @Test
public void indexGreetsAuthenticatedUser() { public void indexGreetsAuthenticatedUser() {
this.rest.mutateWith(mockJwt(jwt -> jwt.subject("test-subject"))) this.rest.mutateWith(mockJwt().jwt(jwt -> jwt.subject("test-subject")))
.get().uri("/").exchange() .get().uri("/").exchange()
.expectBody(String.class).isEqualTo("Hello, test-subject!"); .expectBody(String.class).isEqualTo("Hello, test-subject!");
} }
@Test @Test
public void messageCanBeReadWithScopeMessageReadAuthority() { public void messageCanBeReadWithScopeMessageReadAuthority() {
this.rest.mutateWith(mockJwt(jwt -> jwt.claim("scope", "message:read"))) this.rest.mutateWith(mockJwt().jwt(jwt -> jwt.claim("scope", "message:read")))
.get().uri("/message").exchange() .get().uri("/message").exchange()
.expectBody(String.class).isEqualTo("secret message"); .expectBody(String.class).isEqualTo("secret message");

View File

@ -47,13 +47,13 @@ public class OAuth2ResourceServerControllerTests {
@Test @Test
public void indexGreetsAuthenticatedUser() throws Exception { public void indexGreetsAuthenticatedUser() throws Exception {
mockMvc.perform(get("/").with(jwt(jwt -> jwt.subject("ch4mpy")))) mockMvc.perform(get("/").with(jwt().jwt(jwt -> jwt.subject("ch4mpy"))))
.andExpect(content().string(is("Hello, ch4mpy!"))); .andExpect(content().string(is("Hello, ch4mpy!")));
} }
@Test @Test
public void messageCanBeReadWithScopeMessageReadAuthority() throws Exception { public void messageCanBeReadWithScopeMessageReadAuthority() throws Exception {
mockMvc.perform(get("/message").with(jwt(jwt -> jwt.claim("scope", "message:read")))) mockMvc.perform(get("/message").with(jwt().jwt(jwt -> jwt.claim("scope", "message:read"))))
.andExpect(content().string(is("secret message"))); .andExpect(content().string(is("secret message")));
mockMvc.perform(get("/message") mockMvc.perform(get("/message")
@ -79,7 +79,7 @@ public class OAuth2ResourceServerControllerTests {
public void messageCanNotBeCreatedWithScopeMessageReadAuthority() throws Exception { public void messageCanNotBeCreatedWithScopeMessageReadAuthority() throws Exception {
mockMvc.perform(post("/message") mockMvc.perform(post("/message")
.content("Hello message") .content("Hello message")
.with(jwt(jwt -> jwt.claim("scope", "message:read")))) .with(jwt().jwt(jwt -> jwt.claim("scope", "message:read"))))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
} }
@ -88,7 +88,7 @@ public class OAuth2ResourceServerControllerTests {
throws Exception { throws Exception {
mockMvc.perform(post("/message") mockMvc.perform(post("/message")
.content("Hello message") .content("Hello message")
.with(jwt(jwt -> jwt.claim("scope", "message:write")))) .with(jwt().jwt(jwt -> jwt.claim("scope", "message:write"))))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string(is("Message was created. Content: Hello message"))); .andExpect(content().string(is("Message was created. Content: Hello message")));
} }

View File

@ -127,42 +127,7 @@ public class SecurityMockServerConfigurers {
* @since 5.2 * @since 5.2
*/ */
public static JwtMutator mockJwt() { public static JwtMutator mockJwt() {
return mockJwt(jwt -> {}); return new JwtMutator();
}
/**
* Updates the ServerWebExchange to 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.
*
* @param jwtBuilderConsumer For configuring the underlying {@link Jwt}
* @return the {@link JwtMutator} to further configure or use
* @since 5.2
*/
public static JwtMutator mockJwt(Consumer<Jwt.Builder> jwtBuilderConsumer) {
Jwt.Builder jwtBuilder = Jwt.withTokenValue("token")
.header("alg", "none")
.claim(SUB, "user")
.claim("scope", "read");
jwtBuilderConsumer.accept(jwtBuilder);
return new JwtMutator(jwtBuilder.build());
}
/**
* Updates the ServerWebExchange to 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.
*
* @param jwt The preliminary constructed {@link Jwt}
* @return the {@link JwtMutator} to further configure or use
* @since 5.2
*/
public static JwtMutator mockJwt(Jwt jwt) {
return new JwtMutator(jwt);
} }
public static CsrfMutator csrf() { public static CsrfMutator csrf() {
@ -361,11 +326,45 @@ public class SecurityMockServerConfigurers {
*/ */
public static class JwtMutator implements WebTestClientConfigurer, MockServerConfigurer { public static class JwtMutator implements WebTestClientConfigurer, MockServerConfigurer {
private Jwt jwt; private Jwt jwt;
private Collection<GrantedAuthority> authorities; private Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter =
new JwtGrantedAuthoritiesConverter();
private JwtMutator(Jwt jwt) { private JwtMutator() {
jwt((jwt) -> {});
}
/**
* Use the given {@link Jwt.Builder} {@link Consumer} to configure the underlying {@link Jwt}
*
* This method first creates a default {@link Jwt.Builder} instance with default values for
* the {@code alg}, {@code sub}, and {@code scope} claims. The {@link Consumer} can then modify
* these or provide additional configuration.
*
* Calling {@link SecurityMockServerConfigurers#mockJwt()} is the equivalent of calling
* {@code SecurityMockMvcRequestPostProcessors.mockJwt().jwt(() -> {})}.
*
* @param jwtBuilderConsumer For configuring the underlying {@link Jwt}
* @return the {@link JwtMutator} for further configuration
*/
public JwtMutator jwt(Consumer<Jwt.Builder> jwtBuilderConsumer) {
Jwt.Builder jwtBuilder = Jwt.withTokenValue("token")
.header("alg", "none")
.claim(SUB, "user")
.claim("scope", "read");
jwtBuilderConsumer.accept(jwtBuilder);
this.jwt = jwtBuilder.build();
return this;
}
/**
* Use the given {@link Jwt}
*
* @param jwt The {@link Jwt} to use
* @return the {@link JwtMutator} for further configuration
*/
public JwtMutator jwt(Jwt jwt) {
this.jwt = jwt; this.jwt = jwt;
this.authorities = new JwtGrantedAuthoritiesConverter().convert(jwt); return this;
} }
/** /**
@ -375,7 +374,7 @@ public class SecurityMockServerConfigurers {
*/ */
public JwtMutator authorities(Collection<GrantedAuthority> authorities) { public JwtMutator authorities(Collection<GrantedAuthority> authorities) {
Assert.notNull(authorities, "authorities cannot be null"); Assert.notNull(authorities, "authorities cannot be null");
this.authorities = authorities; this.authoritiesConverter = jwt -> authorities;
return this; return this;
} }
@ -386,7 +385,7 @@ public class SecurityMockServerConfigurers {
*/ */
public JwtMutator authorities(GrantedAuthority... authorities) { public JwtMutator authorities(GrantedAuthority... authorities) {
Assert.notNull(authorities, "authorities cannot be null"); Assert.notNull(authorities, "authorities cannot be null");
this.authorities = Arrays.asList(authorities); this.authoritiesConverter = jwt -> Arrays.asList(authorities);
return this; return this;
} }
@ -400,7 +399,7 @@ public class SecurityMockServerConfigurers {
*/ */
public JwtMutator authorities(Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter) { public JwtMutator authorities(Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter) {
Assert.notNull(authoritiesConverter, "authoritiesConverter cannot be null"); Assert.notNull(authoritiesConverter, "authoritiesConverter cannot be null");
this.authorities = authoritiesConverter.convert(this.jwt); this.authoritiesConverter = authoritiesConverter;
return this; return this;
} }
@ -427,7 +426,7 @@ public class SecurityMockServerConfigurers {
} }
private <T extends WebTestClientConfigurer & MockServerConfigurer> T configurer() { private <T extends WebTestClientConfigurer & MockServerConfigurer> T configurer() {
return mockAuthentication(new JwtAuthenticationToken(this.jwt, this.authorities)); return mockAuthentication(new JwtAuthenticationToken(this.jwt, this.authoritiesConverter.convert(this.jwt)));
} }
} }
} }

View File

@ -227,70 +227,7 @@ public final class SecurityMockMvcRequestPostProcessors {
* @return the {@link JwtRequestPostProcessor} for additional customization * @return the {@link JwtRequestPostProcessor} for additional customization
*/ */
public static JwtRequestPostProcessor jwt() { public static JwtRequestPostProcessor jwt() {
return jwt(jwt -> {}); return new JwtRequestPostProcessor();
}
/**
* 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.
*
* <p>
* 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:
* </p>
*
* <ul>
* <li>Invoking apply {@link SecurityMockMvcConfigurers#springSecurity()}</li>
* <li>Adding Spring Security's FilterChainProxy to MockMvc</li>
* <li>Manually adding {@link SecurityContextPersistenceFilter} to the MockMvc
* instance may make sense when using MockMvcBuilders standaloneSetup</li>
* </ul>
*
* @param jwtBuilderConsumer For configuring the underlying {@link Jwt}
* @return the {@link JwtRequestPostProcessor} for additional customization
* @since 5.2
*/
public static JwtRequestPostProcessor jwt(Consumer<Jwt.Builder> jwtBuilderConsumer) {
Jwt.Builder jwtBuilder = Jwt.withTokenValue("token")
.header("alg", "none")
.claim(SUB, "user")
.claim("scope", "read");
jwtBuilderConsumer.accept(jwtBuilder);
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.
*
* <p>
* 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:
* </p>
*
* <ul>
* <li>Invoking apply {@link SecurityMockMvcConfigurers#springSecurity()}</li>
* <li>Adding Spring Security's FilterChainProxy to MockMvc</li>
* <li>Manually adding {@link SecurityContextPersistenceFilter} to the MockMvc
* instance may make sense when using MockMvcBuilders standaloneSetup</li>
* </ul>
*
* @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);
} }
/** /**
@ -1000,11 +937,45 @@ public final class SecurityMockMvcRequestPostProcessors {
*/ */
public final static class JwtRequestPostProcessor implements RequestPostProcessor { public final static class JwtRequestPostProcessor implements RequestPostProcessor {
private Jwt jwt; private Jwt jwt;
private Collection<? extends GrantedAuthority> authorities; private Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter =
new JwtGrantedAuthoritiesConverter();
private JwtRequestPostProcessor(Jwt jwt) { private JwtRequestPostProcessor() {
this.jwt((jwt) -> {});
}
/**
* Use the given {@link Jwt.Builder} {@link Consumer} to configure the underlying {@link Jwt}
*
* This method first creates a default {@link Jwt.Builder} instance with default values for
* the {@code alg}, {@code sub}, and {@code scope} claims. The {@link Consumer} can then modify
* these or provide additional configuration.
*
* Calling {@link SecurityMockMvcRequestPostProcessors#jwt()} is the equivalent of calling
* {@code SecurityMockMvcRequestPostProcessors.jwt().jwt(() -> {})}.
*
* @param jwtBuilderConsumer For configuring the underlying {@link Jwt}
* @return the {@link JwtRequestPostProcessor} for additional customization
*/
public JwtRequestPostProcessor jwt(Consumer<Jwt.Builder> jwtBuilderConsumer) {
Jwt.Builder jwtBuilder = Jwt.withTokenValue("token")
.header("alg", "none")
.claim(SUB, "user")
.claim("scope", "read");
jwtBuilderConsumer.accept(jwtBuilder);
this.jwt = jwtBuilder.build();
return this;
}
/**
* Use the given {@link Jwt}
*
* @param jwt The {@link Jwt} to use
* @return the {@link JwtRequestPostProcessor} for additional customization
*/
public JwtRequestPostProcessor jwt(Jwt jwt) {
this.jwt = jwt; this.jwt = jwt;
this.authorities = new JwtGrantedAuthoritiesConverter().convert(jwt); return this;
} }
/** /**
@ -1014,7 +985,7 @@ public final class SecurityMockMvcRequestPostProcessors {
*/ */
public JwtRequestPostProcessor authorities(Collection<GrantedAuthority> authorities) { public JwtRequestPostProcessor authorities(Collection<GrantedAuthority> authorities) {
Assert.notNull(authorities, "authorities cannot be null"); Assert.notNull(authorities, "authorities cannot be null");
this.authorities = authorities; this.authoritiesConverter = jwt -> authorities;
return this; return this;
} }
@ -1025,7 +996,7 @@ public final class SecurityMockMvcRequestPostProcessors {
*/ */
public JwtRequestPostProcessor authorities(GrantedAuthority... authorities) { public JwtRequestPostProcessor authorities(GrantedAuthority... authorities) {
Assert.notNull(authorities, "authorities cannot be null"); Assert.notNull(authorities, "authorities cannot be null");
this.authorities = Arrays.asList(authorities); this.authoritiesConverter = jwt -> Arrays.asList(authorities);
return this; return this;
} }
@ -1039,14 +1010,15 @@ public final class SecurityMockMvcRequestPostProcessors {
*/ */
public JwtRequestPostProcessor authorities(Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter) { public JwtRequestPostProcessor authorities(Converter<Jwt, Collection<GrantedAuthority>> authoritiesConverter) {
Assert.notNull(authoritiesConverter, "authoritiesConverter cannot be null"); Assert.notNull(authoritiesConverter, "authoritiesConverter cannot be null");
this.authorities = authoritiesConverter.convert(this.jwt); this.authoritiesConverter = authoritiesConverter;
return this; return this;
} }
@Override @Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) { public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
CsrfFilter.skipRequest(request); CsrfFilter.skipRequest(request);
JwtAuthenticationToken token = new JwtAuthenticationToken(this.jwt, this.authorities); JwtAuthenticationToken token = new JwtAuthenticationToken(this.jwt,
this.authoritiesConverter.convert(this.jwt));
return new AuthenticationRequestPostProcessor(token).postProcessRequest(request); return new AuthenticationRequestPostProcessor(token).postProcessRequest(request);
} }

View File

@ -85,7 +85,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
public void mockJwtWhenProvidingBuilderConsumerThenProducesJwtAuthentication() { public void mockJwtWhenProvidingBuilderConsumerThenProducesJwtAuthentication() {
String name = new String("user"); String name = new String("user");
client client
.mutateWith(mockJwt(jwt -> jwt.subject(name))) .mutateWith(mockJwt().jwt(jwt -> jwt.subject(name)))
.get() .get()
.exchange() .exchange()
.expectStatus().isOk(); .expectStatus().isOk();
@ -100,7 +100,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
@Test @Test
public void mockJwtWhenProvidingCustomAuthoritiesThenProducesJwtAuthentication() { public void mockJwtWhenProvidingCustomAuthoritiesThenProducesJwtAuthentication() {
client client
.mutateWith(mockJwt(jwt -> jwt.claim("scope", "ignored authorities")) .mutateWith(mockJwt().jwt(jwt -> jwt.claim("scope", "ignored authorities"))
.authorities(this.authority1, this.authority2)) .authorities(this.authority1, this.authority2))
.get() .get()
.exchange() .exchange()
@ -114,7 +114,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
@Test @Test
public void mockJwtWhenProvidingScopedAuthoritiesThenProducesJwtAuthentication() { public void mockJwtWhenProvidingScopedAuthoritiesThenProducesJwtAuthentication() {
client client
.mutateWith(mockJwt(jwt -> jwt.claim("scope", "scoped authorities"))) .mutateWith(mockJwt().jwt(jwt -> jwt.claim("scope", "scoped authorities")))
.get() .get()
.exchange() .exchange()
.expectStatus().isOk(); .expectStatus().isOk();
@ -128,7 +128,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
@Test @Test
public void mockJwtWhenProvidingGrantedAuthoritiesThenProducesJwtAuthentication() { public void mockJwtWhenProvidingGrantedAuthoritiesThenProducesJwtAuthentication() {
client client
.mutateWith(mockJwt(jwt -> jwt.claim("scope", "ignored authorities")) .mutateWith(mockJwt().jwt(jwt -> jwt.claim("scope", "ignored authorities"))
.authorities(jwt -> Arrays.asList(this.authority1))) .authorities(jwt -> Arrays.asList(this.authority1)))
.get() .get()
.exchange() .exchange()
@ -146,7 +146,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
.subject("some_user") .subject("some_user")
.build(); .build();
this.client this.client
.mutateWith(mockJwt(originalToken)) .mutateWith(mockJwt().jwt(originalToken))
.get() .get()
.exchange() .exchange()
.expectStatus().isOk(); .expectStatus().isOk();

View File

@ -107,7 +107,7 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
@Test @Test
public void jwtWhenProvidingBuilderConsumerThenProducesJwtAuthentication() { public void jwtWhenProvidingBuilderConsumerThenProducesJwtAuthentication() {
String name = new String("user"); String name = new String("user");
jwt(jwt -> jwt.subject(name)).postProcessRequest(this.request); jwt().jwt(jwt -> jwt.subject(name)).postProcessRequest(this.request);
verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request), verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
any(HttpServletResponse.class)); any(HttpServletResponse.class));
@ -120,7 +120,7 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
@Test @Test
public void jwtWhenProvidingCustomAuthoritiesThenProducesJwtAuthentication() { public void jwtWhenProvidingCustomAuthoritiesThenProducesJwtAuthentication() {
jwt(jwt -> jwt.claim("scope", "ignored authorities")) jwt().jwt(jwt -> jwt.claim("scope", "ignored authorities"))
.authorities(this.authority1, this.authority2) .authorities(this.authority1, this.authority2)
.postProcessRequest(this.request); .postProcessRequest(this.request);
@ -133,7 +133,7 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
@Test @Test
public void jwtWhenProvidingScopedAuthoritiesThenProducesJwtAuthentication() { public void jwtWhenProvidingScopedAuthoritiesThenProducesJwtAuthentication() {
jwt(jwt -> jwt.claim("scope", "scoped authorities")) jwt().jwt(jwt -> jwt.claim("scope", "scoped authorities"))
.postProcessRequest(this.request); .postProcessRequest(this.request);
verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request), verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
@ -146,7 +146,7 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
@Test @Test
public void jwtWhenProvidingGrantedAuthoritiesThenProducesJwtAuthentication() { public void jwtWhenProvidingGrantedAuthoritiesThenProducesJwtAuthentication() {
jwt(jwt -> jwt.claim("scope", "ignored authorities")) jwt().jwt(jwt -> jwt.claim("scope", "ignored authorities"))
.authorities(jwt -> Arrays.asList(this.authority1)) .authorities(jwt -> Arrays.asList(this.authority1))
.postProcessRequest(this.request); .postProcessRequest(this.request);
@ -163,7 +163,7 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
.header("header1", "value1") .header("header1", "value1")
.subject("some_user") .subject("some_user")
.build(); .build();
jwt(originalToken).postProcessRequest(this.request); jwt().jwt(originalToken).postProcessRequest(this.request);
verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request), verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
any(HttpServletResponse.class)); any(HttpServletResponse.class));