Hi!
I just updated several services to SpringBoot 2.1.3 and observed a different behavior regarding integration tests in WebFlux and WebMVC in combination with spring-security.
In both services a custom SecurityConfig exists.
In the WebMVC service the config looks like:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// custom config is here
}
}
In the WebFlux service the config looks like:
@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {
@Bean
public SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
//custom config is here
}
}
When implementing an integration test using @WebMvcTest
the custom WebSecurityConfig is called (placing a breakpoint in the configure method works). But in order to be active it is necessary to callapply(SecurityMockMvcConfigurers.springSecurity())
on the MockMvcBuilder
.
I think this is in line with the documentation provided here:
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#test-mockmvc-setup
When implementing an integration test using @WebFluxTest
the custom SecurityConfiguration is not called, but instead the standard org.springframework.security.config.annotation.web.reactive.WebFluxSecurityConfiguration
is used. I have to use @Import
on the test class to get the custom SecurityConfiguration to work.
I couldn't find anything in the documentation that describes this behavior of @WebFluxTest
. I would expect that @WebFluxTest
behaves like @WebMvcTest
and uses the custom SecurityConfiguration.
Comment From: dkroehan
Related to: https://github.com/spring-projects/spring-boot/issues/6514
Comment From: mbhave
@dkroehan @WebFluxTest
should pick up the custom security configuration. Can you provide a minimal sample that we can run to reproduce the issue?
Comment From: dkroehan
@mbhave I added a sample application here: https://github.com/dkroehan/webfluxtest
Comment From: snicoll
@dkroehan your Webflux security does not inherit from ServerHttpSecurity
so we can't detect it (notice that the MVC counterpart is extending from Spring Security's base class).
Comment From: dkroehan
@snicoll Is this documented anywhere?
I checked spring-security docs: https://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#minimal-webflux-security-configuration https://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#test-webflux
and the Javadoc: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurity.html https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/web/server/ServerHttpSecurity.html
None of these examples shows this.
Comment From: wilkinsona
your Webflux security does not inherit from ServerHttpSecurity
I don't think it should. The ServerHttpSecurity
bean is provided by Spring Security, not a user's application.
Comment From: snicoll
🤷♂️
Comment From: mbhave
@wilkinsona is right. This is a bug in WebFluxTypeExcludeFilter
. It should include SecurityWebFilterChain
beans rather than ServerHttpSecurity
.
Comment From: mbhave
Actually, the problem is broader than just fixing the type in WebFluxTypeExcludeFilter
. WebFluxTypeExcludeFilter
only applies to beans created by component scanning. When you have something like this:
@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {
@Bean
public SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
//custom config is here
}
}
The WebFluxTypeExcludeFilter
doesn't include @Configuration
classes and SecurityWebFilterChain
which is not created by component scanning doesn't get picked up.
@dkroehan As a workaround, you could add @Import(SecurityConfiguration.class)
in the test class.
Comment From: mbhave
We discussed this and it would be quite a big change for 2.1.x
. We'll document the limitation for now.
Comment From: kevhussey
@mbhave - Thank you for this. I also ran into this problem. I finally got my test to work by adding
@Import(SecurityConfig.class)
@WithMockUser
on class level.
Comment From: brnhffmnn
@mbhave this issue seems stale. Is there any progress or other workaround that doesn't require to adjust all my test classes?
Comment From: wilkinsona
This has come up again recently. I wonder if we can do something in 2.7 or early in the 2.6.x maintenance releases?