2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								[[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]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`) or the function must be a Kotlin coroutine function.
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								This is necessary to integrate with Reactor's `Context`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,java,role="primary"]
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Mono<String> 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();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="secondary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								val authentication: Authentication = TestingAuthenticationToken("user", "password", "ROLE_USER")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								val messageByUsername: Mono<String> = 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()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								with `this::findMessageByUsername` defined as:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,java,role="primary"]
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Mono<String> findMessageByUsername(String username) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return Mono.just("Hi " + username);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="secondary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								fun findMessageByUsername(username: String): Mono<String> {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return Mono.just("Hi $username")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								Below is a minimal method security configuration when using method security in reactive applications.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,java,role="primary"]
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@EnableReactiveMethodSecurity
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public class SecurityConfig {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@Bean
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									public MapReactiveUserDetailsService userDetailsService() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										User.UserBuilder userBuilder = User.withDefaultPasswordEncoder();
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 22:39:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										UserDetails rob = userBuilder.username("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserDetails admin = userBuilder.username("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER","ADMIN")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build();
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return new MapReactiveUserDetailsService(rob, admin);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="secondary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@EnableReactiveMethodSecurity
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class SecurityConfig {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@Bean
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fun userDetailsService(): MapReactiveUserDetailsService {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val userBuilder: User.UserBuilder = User.withDefaultPasswordEncoder()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val rob = userBuilder.username("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val admin = userBuilder.username("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER", "ADMIN")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return MapReactiveUserDetailsService(rob, admin)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								Consider the following class:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,java,role="primary"]
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@Component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public class HelloWorldMessageService {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@PreAuthorize("hasRole('ADMIN')")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									public Mono<String> findMessage() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return Mono.just("Hello World!");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="secondary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@Component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class HelloWorldMessageService {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@PreAuthorize("hasRole('ADMIN')")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fun findMessage(): Mono<String> {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return Mono.just("Hello World!")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Or, the following class using Kotlin coroutines:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="primary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@Component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class HelloWorldMessageService {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @PreAuthorize("hasRole('ADMIN')")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    suspend fun findMessage(): String {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        delay(10)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return "Hello World!"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								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.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-21 15:54:30 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								When integrating with xref:reactive/configuration/webflux.adoc#jc-webflux[WebFlux Security], the Reactor Context is automatically established by Spring Security according to the authenticated user.
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.Java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,java,role="primary"]
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@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
							 
						 
					
						
							
								
									
										
										
										
											2020-01-10 13:10:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											.authorizeExchange(exchanges -> exchanges
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												.anyExchange().permitAll()
							 
						 
					
						
							
								
									
										
										
										
											2019-07-22 09:31:10 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.httpBasic(withDefaults())
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											.build();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@Bean
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MapReactiveUserDetailsService userDetailsService() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										User.UserBuilder userBuilder = User.withDefaultPasswordEncoder();
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 22:39:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										UserDetails rob = userBuilder.username("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserDetails admin = userBuilder.username("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER","ADMIN")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build();
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 21:01:07 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return new MapReactiveUserDetailsService(rob, admin);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-09 13:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.Kotlin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								[source,kotlin,role="secondary"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@EnableWebFluxSecurity
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@EnableReactiveMethodSecurity
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class SecurityConfig {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@Bean
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return http {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											authorizeExchange {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												authorize(anyExchange, permitAll)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											httpBasic { }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@Bean
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fun userDetailsService(): MapReactiveUserDetailsService {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val userBuilder: User.UserBuilder = User.withDefaultPasswordEncoder()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val rob = userBuilder.username("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("rob")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val admin = userBuilder.username("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.password("admin")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.roles("USER", "ADMIN")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											.build()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return MapReactiveUserDetailsService(rob, admin)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								----
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 09:56:05 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								You can find a complete sample in {gh-samples-url}/reactive/webflux/java/method[hellowebflux-method]