# WebFlux Security Spring Security’s WebFlux support relies on a `WebFilter` and works the same for Spring WebFlux and Spring WebFlux.Fn. You can find a few sample applications that demonstrate the code below: * Hello WebFlux [hellowebflux](https://github.com/spring-projects/spring-security-samples/tree/5.6.x/reactive/webflux/java/hello-security) * Hello WebFlux.Fn [hellowebfluxfn](https://github.com/spring-projects/spring-security-samples/tree/5.6.x/reactive/webflux-fn/hello-security) * Hello WebFlux Method [hellowebflux-method](https://github.com/spring-projects/spring-security-samples/tree/5.6.x/reactive/webflux/java/method) ## Minimal WebFlux Security Configuration You can find a minimal WebFlux Security configuration below: Example 1. Minimal WebFlux Security Configuration Java ``` @EnableWebFluxSecurity public class HelloWebfluxSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("user") .roles("USER") .build(); return new MapReactiveUserDetailsService(user); } } ``` Kotlin ``` @EnableWebFluxSecurity class HelloWebfluxSecurityConfig { @Bean fun userDetailsService(): ReactiveUserDetailsService { val userDetails = User.withDefaultPasswordEncoder() .username("user") .password("user") .roles("USER") .build() return MapReactiveUserDetailsService(userDetails) } } ``` This configuration provides form and http basic authentication, sets up authorization to require an authenticated user for accessing any page, sets up a default log in page and a default log out page, sets up security related HTTP headers, CSRF protection, and more. ## Explicit WebFlux Security Configuration You can find an explicit version of the minimal WebFlux Security configuration below: Example 2. Explicit WebFlux Security Configuration Java ``` @Configuration @EnableWebFluxSecurity public class HelloWebfluxSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("user") .roles("USER") .build(); return new MapReactiveUserDetailsService(user); } @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http .authorizeExchange(exchanges -> exchanges .anyExchange().authenticated() ) .httpBasic(withDefaults()) .formLogin(withDefaults()); return http.build(); } } ``` Kotlin ``` @Configuration @EnableWebFluxSecurity class HelloWebfluxSecurityConfig { @Bean fun userDetailsService(): ReactiveUserDetailsService { val userDetails = User.withDefaultPasswordEncoder() .username("user") .password("user") .roles("USER") .build() return MapReactiveUserDetailsService(userDetails) } @Bean fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { return http { authorizeExchange { authorize(anyExchange, authenticated) } formLogin { } httpBasic { } } } } ``` This configuration explicitly sets up all the same things as our minimal configuration. From here you can easily make the changes to the defaults. You can find more examples of explicit configuration in unit tests, by searching [EnableWebFluxSecurity in the `config/src/test/` directory](https://github.com/spring-projects/spring-security/search?q=path%3Aconfig%2Fsrc%2Ftest%2F+EnableWebFluxSecurity). ### Multiple Chains Support You can configure multiple `SecurityWebFilterChain` instances to separate configuration by `RequestMatcher`s. For example, you can isolate configuration for URLs that start with `/api`, like so: Java ``` @Configuration @EnableWebFluxSecurity static class MultiSecurityHttpConfig { @Order(Ordered.HIGHEST_PRECEDENCE) (1) @Bean SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) { http .securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**")) (2) .authorizeExchange((exchanges) -> exchanges .anyExchange().authenticated() ) .oauth2ResourceServer(OAuth2ResourceServerSpec::jwt); (3) return http.build(); } @Bean SecurityWebFilterChain webHttpSecurity(ServerHttpSecurity http) { (4) http .authorizeExchange((exchanges) -> exchanges .anyExchange().authenticated() ) .httpBasic(withDefaults()); (5) return http.build(); } @Bean ReactiveUserDetailsService userDetailsService() { return new MapReactiveUserDetailsService( PasswordEncodedUser.user(), PasswordEncodedUser.admin()); } } ``` Kotlin ``` @Configuration @EnableWebFluxSecurity open class MultiSecurityHttpConfig { @Order(Ordered.HIGHEST_PRECEDENCE) (1) @Bean open fun apiHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain { return http { securityMatcher(PathPatternParserServerWebExchangeMatcher("/api/**")) (2) authorizeExchange { authorize(anyExchange, authenticated) } oauth2ResourceServer { jwt { } (3) } } } @Bean open fun webHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain { (4) return http { authorizeExchange { authorize(anyExchange, authenticated) } httpBasic { } (5) } } @Bean open fun userDetailsService(): ReactiveUserDetailsService { return MapReactiveUserDetailsService( PasswordEncodedUser.user(), PasswordEncodedUser.admin() ) } } ``` |**1**| Configure a `SecurityWebFilterChain` with an `@Order` to specify which `SecurityWebFilterChain` Spring Security should consider first | |-----|------------------------------------------------------------------------------------------------------------------------------------------------| |**2**|Use `PathPatternParserServerWebExchangeMatcher` to state that this `SecurityWebFilterChain` will only apply to URL paths that start with `/api/`| |**3**| Specify the authentication mechanisms that will be used for `/api/**` endpoints | |**4**| Create another instance of `SecurityWebFilterChain` with lower precedence to match all other URLs | |**5**| Specify the authentication mechanisms that will be used for the rest of the application | Spring Security will select one `SecurityWebFilterChain` `@Bean` for each request. It will match the requests in order by the `securityMatcher` definition. In this case, that means that if the URL path starts with `/api`, then Spring Security will use `apiHttpSecurity`. If the URL does not start with `/api` then Spring Security will default to `webHttpSecurity`, which has an implied `securityMatcher` that matches any request.