From 8b7751f5f400d1663b3a8f60885b1837983906ea Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Mon, 2 Nov 2020 12:15:19 -0700 Subject: [PATCH] Polish Multiple Filter Chains Docs Issue gh-9178 --- .../asciidoc/_includes/reactive/webflux.adoc | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc b/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc index b88e1af864..d6a5263a35 100644 --- a/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc @@ -128,57 +128,58 @@ From here you can easily make the changes to the defaults. You can find more examples of explicit configuration in unit tests, by searching https://github.com/spring-projects/spring-security/search?q=path%3Aconfig%2Fsrc%2Ftest%2F+EnableWebFluxSecurity[EnableWebFluxSecurity in the `config/src/test/` directory]. [[jc-webflux-multiple-filter-chains]] -=== Multiple chains support +=== Multiple Chains Support -We can configure multiple `SecurityWebFilterChain` instances. +You can configure multiple `SecurityWebFilterChain` instances to separate configuration by `RequestMatcher` s. -For example, the following is an example of having a specific configuration for URL's that start with `/api/`. This overrides the form login configuration with lower precedence. +For example, you can isolate configuration for URLs that start with `/api`, like so: [source,java] ---- - @EnableWebFluxSecurity - @Import(ReactiveAuthenticationTestConfiguration.class) - static class MultiSecurityHttpConfig { - - @Order(Ordered.HIGHEST_PRECEDENCE) <1> - @Bean - SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) { - http - .securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**")) <2> - .authorizeExchange() - .anyExchange().denyAll(); - return http.build(); - } - - @Bean - SecurityWebFilterChain webFormHttpSecurity(ServerHttpSecurity http) { <3> - http - .authorizeExchange((exchanges) -> - exchanges - .pathMatchers("/login").permitAll() - .anyExchange().authenticated() - ) - .httpBasic(withDefaults()) - .formLogin((formLogin) -> <4> - formLogin - .loginPage("/login") - ); - return http.build(); - } - - @Bean - public static ReactiveUserDetailsService userDetailsService() { - return new MapReactiveUserDetailsService(PasswordEncodedUser.user(), PasswordEncodedUser.admin()); - } +@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()); + } + +} ---- -<1> Configure a SecurityWebFilterChain with an `@Order` to specify which `SecurityWebFilterChain` should be considered first -<2> The `PathPatternParserServerWebExchangeMatcher` states that this `SecurityWebFilterChain` will only be applicable to URLs that start with `/api/` -<3> Create another instance of `SecurityWebFilterChain` with lower precedence. -<4> Some configurations applies to all path matchers within the `webFormHttpSecurity` but not to `apiHttpSecurity` `SecurityWebFilterChain`. +<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. -If the URL does not start with `/api/` the `webFormHttpSecurity` configuration will be used. +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.