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?