https://github.com/spring-projects/spring-security/blob/0295b51e78302eed1fe37ffeb763e8afce0fb1ac/test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java#L173
Clearly there is an error when passing null as httpHandlerBuilder the method throws NPE.
I got this exception when I wanted to use it like this:
@Test
fun `For new account, add initial bank account and update bank account after`() {
...
webTestClient.mutateWith(mockAccessToken(sessionId, memberNumber))
.post().uri("/users/{userId}/bank-account/", mapOf("userId" to userId))
.accept(MediaType.APPLICATION_JSON)
.bodyValue(SaveBankAccountCommand(userId, iban, bic, address))
.exchange()
.expectStatus().isOk
...
}
private fun mockAccessToken(sessionId: ResponseCookie, memberNumber: Int): SecurityMockServerConfigurers.JwtMutator {
return mockJwt { jwt ->
jwt.claim(sessionId.name, sessionId.value)
.subject("f:no-used-part-of-uuid:$userId")
.claim("memberNumber", memberNumber)
}
}
Stacktrace is:
java.lang.NullPointerException
at org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers$JwtMutator.afterConfigurerAdded(SecurityMockServerConfigurers.java:422)
at org.springframework.test.web.reactive.server.DefaultWebTestClientBuilder.apply(DefaultWebTestClientBuilder.java:159)
at org.springframework.test.web.reactive.server.DefaultWebTestClient.mutateWith(DefaultWebTestClient.java:142)
I found no workaround...
Comment From: jzheaux
@mikhail-putilov thanks for reporting this. Would you be able to provide a minimal sample that reproduces this behavior?
Comment From: antoninarq
We encountered the same problem when mocking authentication with .mutateWith():
private static Authentication generateJwtAuth(final Collection<String> roleList) {
final Jwt jwt = new Jwt("test", Instant.MIN, Instant.MAX,
Collections.singletonMap("test", "test"), Collections.singletonMap("test", "test"));
return new JwtAuthenticationToken(jwt,
roleList.streamrolelist.streamundefined().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
}
@Test
void whenPostWithCredentialsThenRequestAccepted() throws Exception {
final Authentication auth = generateJwtAuth(
Collections.singletonList("my_role"));
webTestClient.mutateWith(SecurityMockServerConfigurers.mockAuthentication(auth))
.post()
.uri("/api/0/cats")
.contentType(MediaType.TEXT_PLAIN)
.body(Mono.just(messageTest), String.class)
.exchange()
.expectStatus()
.isOk();
The stacktrace is similar to the one provided above :
java.lang.NullPointerException
at org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers$MutatorWebTestClientConfigurer.afterConfigurerAdded(SecurityMockServerConfigurers.java:317)
at org.springframework.test.web.reactive.server.DefaultWebTestClientBuilder.apply(DefaultWebTestClientBuilder.java:167)
at org.springframework.test.web.reactive.server.DefaultWebTestClient.mutateWith(DefaultWebTestClient.java:142)
We are using spring-security 5.2.1.RELEASE and springboot 2.2.4.RELEASE.
Comment From: antoninarq
To follow up on this, it was due to a mistake in our side while configuring WebFlux security config (we thought it worked similarly as webmvc).
We do not have this problem anymore !
Comment From: jzheaux
@mikhail-putilov is this still an issue for you? If so, would you please provide a minimal sample that demonstrates the issue?
Comment From: jzheaux
@antoninarq glad you got it working! Would you mind sharing what difference you found? It may help make the documentation clearer.
Comment From: antoninarq
@jzheaux we had a library that configure our springboot projects with a :
public class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
For new projects that used webflux we did not understood that we needed to use a SecurityWebFilterChain bean. When we understood that, we did not have too much trouble implementing the same security behavior as WebMvc, the document was quite clear.
Maybe it should be more strongly said in the documentation that the two flavors have different security configurations.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Comment From: luvarqpp
I have setup with .sessionCreationPolicy(SessionCreationPolicy.STATELESS), custom .authenticationEntryPoint(new RestAuthenticationEntryPoint()), .oauth2Login(), custom .userInfoEndpoint().userService(customOAuth2UserService) and also custom auth filter http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);. I have triggered this NPE by using webTestClientBuilder.build().mutateWith(csrf()) call (failed in SecurityMockServerConfigurers.CsrfMutator, like this issue).
On the other side, it seems OK, to have csrf disabled, when using Authorization header with Bearer token and having redirect restriction (due "referrer" header) on authorization server.
Comment From: straurob
@jzheaux we had a library that configure our springboot projects with a :
java public class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapterFor new projects that used webflux we did not understood that we needed to use a
SecurityWebFilterChainbean. When we understood that, we did not have too much trouble implementing the same security behavior as WebMvc, the document was quite clear.Maybe it should be more strongly said in the documentation that the two flavors have different security configurations.
I'm running into the exactly same issue. I tried to use a SecurityFilterChain instead of extending from WebSecurityConfigurerAdapter but now I cannot use super.authenticationManagerBean() to get an AuthenticationManager. Do you have any advice on this or a small code example?
Comment From: jzheaux
@straurob I think this is something that's still being investigated but is not supported right now as in many cases it's quite simple to construct your own AuthenticationManager.
Newer support is less reliant on a globally-configured AuthenticationManager, and so I think it would be good to understand more about your specific use case and why you need to publish an AuthenticationManager as a bean. Would you please file a separate ticket describing your situation?