diff --git a/docs/manual/src/docs/asciidoc/_includes/reactive/index.adoc b/docs/manual/src/docs/asciidoc/_includes/reactive/index.adoc new file mode 100644 index 0000000000..450016414b --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/reactive/index.adoc @@ -0,0 +1,7 @@ += Reactive Applications + +include::webflux.adoc[leveloffset=+1] + +include::method.adoc[leveloffset=+1] + +include::webtestclient.adoc[leveloffset=+1] diff --git a/docs/manual/src/docs/asciidoc/_includes/reactive/method.adoc b/docs/manual/src/docs/asciidoc/_includes/reactive/method.adoc new file mode 100644 index 0000000000..0f87aaef1a --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/reactive/method.adoc @@ -0,0 +1,103 @@ +[[jc-erms]] += EnableReactiveMethodSecurity + +Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`. +For example, this demonstrates how to retrieve the currently logged in user's message. + +[NOTE] +==== +For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`). +This is necessary to integrate with Reactor's `Context`. +==== + +[source,java] +---- +Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER"); + +Mono messageByUsername = ReactiveSecurityContextHolder.getContext() + .map(SecurityContext::getAuthentication) + .map(Authentication::getName) + .flatMap(this::findMessageByUsername) + // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter` + .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication)); + +StepVerifier.create(messageByUsername) + .expectNext("Hi user") + .verifyComplete(); +---- + +with `this::findMessageByUsername` defined as: + +[source,java] +---- +Mono findMessageByUsername(String username) { + return Mono.just("Hi " + username); +} +---- + +Below is a minimal method security configuration when using method security in reactive applications. + +[source,java] +---- +@EnableReactiveMethodSecurity +public class SecurityConfig { + @Bean + public MapReactiveUserDetailsService userDetailsService() { + User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); + UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); + UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); + return new MapReactiveUserDetailsService(rob, admin); + } +} +---- + +Consider the following class: + +[source,java] +---- +@Component +public class HelloWorldMessageService { + @PreAuthorize("hasRole('ADMIN')") + public Mono findMessage() { + return Mono.just("Hello World!"); + } +} +---- + +Combined with our configuration above, `@PreAuthorize("hasRole('ADMIN')")` will ensure that `findByMessage` is only invoked by a user with the role `ADMIN`. +It is important to note that any of the expressions in standard method security work for `@EnableReactiveMethodSecurity`. +However, at this time we only support return type of `Boolean` or `boolean` of the expression. +This means that the expression must not block. + +When integrating with <>, the Reactor Context is automatically established by Spring Security according to the authenticated user. + +[source,java] +---- +@EnableWebFluxSecurity +@EnableReactiveMethodSecurity +public class SecurityConfig { + + @Bean + SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { + return http + // Demonstrate that method security works + // Best practice to use both for defense in depth + .authorizeExchange() + .anyExchange().permitAll() + .and() + .httpBasic().and() + .build(); + } + + @Bean + MapReactiveUserDetailsService userDetailsService() { + User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); + UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); + UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); + return new MapReactiveUserDetailsService(rob, admin); + } +} + +---- + +You can find a complete sample in {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] diff --git a/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc b/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc new file mode 100644 index 0000000000..8752b8311b --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/reactive/webflux.adoc @@ -0,0 +1,68 @@ +[[jc-webflux]] += 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 {gh-samples-url}/javaconfig/hellowebflux[hellowebflux] +* Hello WebFlux.Fn {gh-samples-url}/javaconfig/hellowebfluxfn[hellowebfluxfn] +* Hello WebFlux Method {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] + + +== Minimal WebFlux Security Configuration + +You can find a minimal WebFlux Security configuration below: + +[source,java] +----- +@EnableWebFluxSecurity +public class HelloWebfluxSecurityConfig { + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("user") + .roles("USER") + .build(); + return new MapReactiveUserDetailsService(user); + } +} +----- + +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: + +[source,java] +----- +@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() + .anyExchange().authenticated() + .and() + .httpBasic().and() + .formLogin(); + return http.build(); + } +} +----- + +This configuration explicitly sets up all the same things as our minimal configuration. +From here you can easily make the changes to the defaults. diff --git a/docs/manual/src/docs/asciidoc/_includes/test/webtestclient.adoc b/docs/manual/src/docs/asciidoc/_includes/reactive/webtestclient.adoc similarity index 96% rename from docs/manual/src/docs/asciidoc/_includes/test/webtestclient.adoc rename to docs/manual/src/docs/asciidoc/_includes/reactive/webtestclient.adoc index 36e319671a..703a944745 100644 --- a/docs/manual/src/docs/asciidoc/_includes/test/webtestclient.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/reactive/webtestclient.adoc @@ -1,8 +1,8 @@ [[test-webflux]] -== WebFlux Support += WebFlux Support [[test-erms]] -=== Reactive Method Security +== Reactive Method Security For example, we can test our example from <> using the same setup and annotations we did in <>. Here is a minimal sample of what we can do: @@ -41,7 +41,7 @@ public class HelloWorldMessageServiceTests { ---- [[test-webtestclient]] -=== WebTestClientSupport +== WebTestClientSupport Spring Security provides integration with `WebTestClient`. The basic setup looks like this: @@ -70,7 +70,7 @@ public class HelloWebfluxMethodApplicationTests { } ---- -==== Authentication +=== Authentication After applying the Spring Security support to `WebTestClient` we can use either annotations or `mutateWith` support. For example: @@ -134,7 +134,7 @@ public void messageWhenMutateWithMockAdminThenOk() throws Exception { ---- -==== CSRF Support +=== CSRF Support Spring Security also provides support for CSRF testing with `WebTestClient`. For example: diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/acls.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/acls.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/acls.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/acls.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/cas.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/cas.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/cas.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/cas.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/concurrency.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/concurrency.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/concurrency.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/concurrency.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/crypto.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/crypto.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/crypto.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/crypto.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/jaas.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/jaas.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/jaas.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/jaas.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/jsp-taglibs.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/jsp-taglibs.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/jsp-taglibs.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/jsp-taglibs.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/ldap.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/ldap.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/ldap.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/ldap.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/mvc.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/mvc.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/mvc.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/mvc.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/oauth2.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/oauth2.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/oauth2.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/oauth2.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/preauth.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/preauth.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/preauth.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/preauth.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/runas.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/runas.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/runas.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/runas.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/additional-topics/x509.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/x509.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/additional-topics/x509.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/additional-topics/x509.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/database-schema.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/database-schema.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/database-schema.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/database-schema.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/dependencies.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/dependencies.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/dependencies.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/dependencies.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/faq.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/faq.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/faq.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/faq.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/namespace.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/namespace.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/namespace.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/namespace.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/appendix/proxy-server.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/appendix/proxy-server.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/appendix/proxy-server.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/appendix/proxy-server.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/core-services.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/architecture/core-services.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/architecture/core-services.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/architecture/core-services.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/architecture/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/architecture/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/architecture/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/jackson.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/architecture/jackson.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/architecture/jackson.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/architecture/jackson.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/password-encoder.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/architecture/password-encoder.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/architecture/password-encoder.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/architecture/password-encoder.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/architecture/technical-overview.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/architecture/technical-overview.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/architecture/technical-overview.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/architecture/technical-overview.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/authorization/architecture.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/authorization/architecture.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/authorization/architecture.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/authorization/architecture.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/authorization/expression-based.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/authorization/expression-based.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/authorization/expression-based.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/authorization/expression-based.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/authorization/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/authorization/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/authorization/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/authorization/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/authorization/secure-objects.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/authorization/secure-objects.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/authorization/secure-objects.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/authorization/secure-objects.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/data/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/data/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/data/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/data/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/servlet/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/index.adoc new file mode 100644 index 0000000000..217607f709 --- /dev/null +++ b/docs/manual/src/docs/asciidoc/_includes/servlet/index.adoc @@ -0,0 +1,17 @@ += Servlet Applications + +include::preface/index.adoc[leveloffset=+1] + +include::architecture/index.adoc[leveloffset=+1] + +include::test/index.adoc[leveloffset=+1] + +include::web/index.adoc[leveloffset=+1] + +include::authorization/index.adoc[leveloffset=+1] + +include::additional-topics/index.adoc[leveloffset=+1] + +include::data/index.adoc[leveloffset=+1] + +include::appendix/index.adoc[leveloffset=+1] diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/community.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/community.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/community.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/community.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/getting-started.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/getting-started.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/getting-started.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/getting-started.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/guides.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/guides.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/guides.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/guides.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/introduction.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/introduction.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/introduction.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/introduction.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/java-configuration.adoc similarity index 90% rename from docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/java-configuration.adoc index 4f2d9ebbef..e52432b2b0 100644 --- a/docs/manual/src/docs/asciidoc/_includes/preface/java-configuration.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/java-configuration.adoc @@ -383,74 +383,6 @@ If not configured a status code 200 will be returned by default. - Section <> (CAS protocol) - Documentation for the <> in the Spring Security XML Namespace section -[[jc-webflux]] -=== 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 {gh-samples-url}/javaconfig/hellowebflux[hellowebflux] -* Hello WebFlux.Fn {gh-samples-url}/javaconfig/hellowebfluxfn[hellowebfluxfn] -* Hello WebFlux Method {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] - - -==== Minimal WebFlux Security Configuration - -You can find a minimal WebFlux Security configuration below: - -[source,java] ------ -@EnableWebFluxSecurity -public class HelloWebfluxSecurityConfig { - - @Bean - public MapReactiveUserDetailsService userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("user") - .password("user") - .roles("USER") - .build(); - return new MapReactiveUserDetailsService(user); - } -} ------ - -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: - -[source,java] ------ -@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() - .anyExchange().authenticated() - .and() - .httpBasic().and() - .formLogin(); - return http.build(); - } -} ------ - -This configuration explicitly sets up all the same things as our minimal configuration. -From here you can easily make the changes to the defaults. [[jc-oauth2login]] === OAuth 2.0 Login @@ -1302,110 +1234,6 @@ public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { For additional information about methods that can be overridden, refer to the `GlobalMethodSecurityConfiguration` Javadoc. -[[jc-erms]] -==== EnableReactiveMethodSecurity - -Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`. -For example, this demonstrates how to retrieve the currently logged in user's message. - -[NOTE] -==== -For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`). -This is necessary to integrate with Reactor's `Context`. -==== - -[source,java] ----- -Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER"); - -Mono messageByUsername = ReactiveSecurityContextHolder.getContext() - .map(SecurityContext::getAuthentication) - .map(Authentication::getName) - .flatMap(this::findMessageByUsername) - // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter` - .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication)); - -StepVerifier.create(messageByUsername) - .expectNext("Hi user") - .verifyComplete(); ----- - -with `this::findMessageByUsername` defined as: - -[source,java] ----- -Mono findMessageByUsername(String username) { - return Mono.just("Hi " + username); -} ----- - -Below is a minimal method security configuration when using method security in reactive applications. - -[source,java] ----- -@EnableReactiveMethodSecurity -public class SecurityConfig { - @Bean - public MapReactiveUserDetailsService userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); - return new MapReactiveUserDetailsService(rob, admin); - } -} ----- - -Consider the following class: - -[source,java] ----- -@Component -public class HelloWorldMessageService { - @PreAuthorize("hasRole('ADMIN')") - public Mono findMessage() { - return Mono.just("Hello World!"); - } -} ----- - -Combined with our configuration above, `@PreAuthorize("hasRole('ADMIN')")` will ensure that `findByMessage` is only invoked by a user with the role `ADMIN`. -It is important to note that any of the expressions in standard method security work for `@EnableReactiveMethodSecurity`. -However, at this time we only support return type of `Boolean` or `boolean` of the expression. -This means that the expression must not block. - -When integrating with <>, the Reactor Context is automatically established by Spring Security according to the authenticated user. - -[source,java] ----- -@EnableWebFluxSecurity -@EnableReactiveMethodSecurity -public class SecurityConfig { - - @Bean - SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { - return http - // Demonstrate that method security works - // Best practice to use both for defense in depth - .authorizeExchange() - .anyExchange().permitAll() - .and() - .httpBasic().and() - .build(); - } - - @Bean - MapReactiveUserDetailsService userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); - return new MapReactiveUserDetailsService(rob, admin); - } -} - ----- - -You can find a complete sample in {gh-samples-url}/javaconfig/hellowebflux-method[hellowebflux-method] - === Post Processing Configured Objects Spring Security's Java Configuration does not expose every property of every object that it configures. diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/namespace.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/namespace.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/namespace.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/namespace.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/samples.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/samples.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/samples.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/samples.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/preface/whats-new.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/preface/whats-new.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/preface/whats-new.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/preface/whats-new.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/test/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/test/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/test/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/test/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/test/method.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/test/method.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/test/method.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/test/method.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/test/mockmvc.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/test/mockmvc.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/test/mockmvc.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/test/mockmvc.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/anonymous.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/anonymous.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/anonymous.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/anonymous.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/basic.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/basic.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/basic.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/basic.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/core-filters.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/core-filters.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/core-filters.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/core-filters.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/cors.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/cors.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/cors.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/cors.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/csrf.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/csrf.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/csrf.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/csrf.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/headers.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/headers.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/headers.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/headers.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/index.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/index.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/index.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/index.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/rememberme.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/rememberme.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/rememberme.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/rememberme.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/security-filter-chain.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/security-filter-chain.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/security-filter-chain.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/security-filter-chain.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/servlet-api.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/servlet-api.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/servlet-api.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/servlet-api.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/session-management.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/session-management.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/session-management.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/session-management.adoc diff --git a/docs/manual/src/docs/asciidoc/_includes/web/websocket.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/web/websocket.adoc similarity index 100% rename from docs/manual/src/docs/asciidoc/_includes/web/websocket.adoc rename to docs/manual/src/docs/asciidoc/_includes/servlet/web/websocket.adoc diff --git a/docs/manual/src/docs/asciidoc/index.adoc b/docs/manual/src/docs/asciidoc/index.adoc index f9cb7cbaff..6cf63fbfee 100644 --- a/docs/manual/src/docs/asciidoc/index.adoc +++ b/docs/manual/src/docs/asciidoc/index.adoc @@ -2,24 +2,15 @@ Ben Alex; Luke Taylor; Rob Winch; Gunnar Hillert; Joe Grandja; Jay Bryant :include-dir: _includes :security-api-url: http://docs.spring.io/spring-security/site/docs/current/apidocs/ +:source-indent: 0 +:tabsize: 2 Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. -include::{include-dir}/preface/index.adoc[] -include::{include-dir}/architecture/index.adoc[] +include::{include-dir}/servlet/index.adoc[] -include::{include-dir}/test/index.adoc[] - -include::{include-dir}/web/index.adoc[] - -include::{include-dir}/authorization/index.adoc[] - -include::{include-dir}/additional-topics/index.adoc[] - -include::{include-dir}/data/index.adoc[] - -include::{include-dir}/appendix/index.adoc[] +include::{include-dir}/reactive/index.adoc[]