Spring Webflux: Security configuration

LE Duc Duy
2 min readAug 7, 2018

--

This post will be about how I got configured Spring Webflux Security. The code can be found on https://github.com/duyleduc/spring-boot-webflux-security

Default Security Setup

Add the spring-boot-security in your pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

This will add @EnableReactiveMethodSecurity containing the initial/default security configuration. To authenticate using username/password, we need a database to store these informations.

Spring boot webflux only supports NoSQL database, in this example, we’ll use reactive mongodb, so add this dependency to your pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

Spring Security Configuration Class

For the security configuration, we’ll create a class SecurityConfiguration with these annotations: @EnableReactiveMethodSecurity and @EnableWebFluxSecurity.

@Configuration
@EnableReactiveMethodSecurity
@EnableWebFluxSecurity
public class
SecurityConfiguration {
}

To complete this configuration, we can take advantage of class ServerHttpSecurity. Next step, provide the following config:

// Disable login form
http.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable();
// Add a filter with Authorization on header http.addFilterAt(webFilter(),SecurityWebFiltersOrder.AUTHORIZATION)
.authorizeExchange()
// Passing a white list endpoint, do not need to
// authenticate
.pathMatchers(AUTH_WHITELIST).permitAll()
.anyExchange().authenticated();

Also, we’ll need a user details service. We must implement the ReactiveUserDetailsService interface

public class ReactiveUserDetailsServiceImpl implements ReactiveUserDetailsService {}

we’ll create an implementation of ServerWebExchangeMatcher to check the authorization header token

public class JWTHeadersExchangeMatcher implements ServerWebExchangeMatcher {}

Then, in the SecurityConfiguration class, create a bean of AuthenticationWebFilter:

@Bean
public
AuthenticationWebFilter webFilter() {
AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(repositoryReactiveAuthenticationManager());
authenticationWebFilter.setAuthenticationConverter(new TokenAuthenticationConverter(tokenProvider));
authenticationWebFilter.setRequiresAuthenticationMatcher(new JWTHeadersExchangeMatcher());
authenticationWebFilter.setSecurityContextRepository(new WebSessionServerSecurityContextRepository());
return authenticationWebFilter;
}

AuthenticationWebFilter needs a token converter, this class will convert a token from ServerWebExchange (HttpRequest not exists anymore in webflux) to a Mono<Authentication>

public class TokenAuthenticationConverter implements Function<ServerWebExchange, Mono<Authentication>> {}

Customize AuthenticateManager

When you want to customize your (JWT) token, for example, add some customized claims, we could create your own AuthenticateManager by the following code:

public class JWTReactiveAuthenticationManin ager implements ReactiveAuthenticationManager {@Override
public
Mono<Authentication> authenticate(final Authentication authentication) {
if (authentication.isAuthenticated()) {
// This can prevent call method get user from database multi times
return Mono.just(authentication);
}
// Customize your implementation here
return Mono.just(authentication)
.switchIfEmpty(Mono.defer(this::raiseBadCredentials))
.cast(UsernamePasswordAuthenticationToken.class)
.flatMap(this::authenticateToken)
.publishOn(Schedulers.parallel())
}
}

This is some feedbacks from some playgrounds about Spring Security in Webflux. All codes are in my github repo:

https://github.com/duyleduc/spring-boot-webflux-security

--

--

Responses (2)