๐ Table of Contents:
- Why Reactive Security?
- Spring Security + WebFlux Basics
- Dependencies for Reactive Security
- Creating a Reactive Security Configuration
- Adding JWT Support
- Custom Authentication Manager
- Securing Routes Based on Roles
- Final Thoughts

๐ 1. Why Reactive Security?
Traditional FilterChain-based security wonโt work effectively in a reactive pipeline. Spring Security for WebFlux provides a reactive security chain using non-blocking authentication, authorization, and session handling.
Benefits:
- Works with Mono/Flux pipelines
- Stateless JWT support
- Non-blocking security filters
๐งฑ 2. Spring Security + WebFlux Basics
Spring Security introduces a different model for reactive apps:
SecurityWebFilterChainreplacesHttpSecurity- Stateless by default
- Can use
ReactiveAuthenticationManager
๐ฆ 3. Dependencies for Reactive Security
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-webflux
io.jsonwebtoken
jjwt
0.9.1
๐งฉ 4. Creating a Reactive Security Configuration
package com.kscodes.springboot.reactive.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/auth/**").permitAll()
.anyExchange().authenticated()
)
.httpBasic().disable()
.formLogin().disable()
.build();
}
}
๐ 5. Adding JWT Support
Token Utility
package com.kscodes.springboot.reactive.util;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "kscodesSecretKey";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hr
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static String extractUsername(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
๐ฎโโ๏ธ 6. Custom Authentication Manager
package com.kscodes.springboot.reactive.security;
import com.kscodes.springboot.reactive.util.JwtUtil;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import java.util.List;
@Component
public class JwtAuthenticationConverter implements ServerAuthenticationConverter {
@Override
public Mono convert(org.springframework.web.server.ServerWebExchange exchange) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (token != null && token.startsWith("Bearer ")) {
String username = JwtUtil.extractUsername(token.substring(7));
return Mono.just(
new UsernamePasswordAuthenticationToken(
username, null, List.of(new SimpleGrantedAuthority("ROLE_USER"))
)
);
}
return Mono.empty();
}
}
You can inject this converter using .authenticationManager(...) in the filter chain.
๐ 7. Securing Routes Based on Roles
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/auth/**").permitAll()
.pathMatchers("/admin/**").hasRole("ADMIN")
.anyExchange().authenticated()
)
โ 8. Final Thoughts
Reactive Security with Spring WebFlux is a powerful way to secure APIs while staying fully non-blocking. With JWT, custom filters, and fine-grained route protection, your application will remain scalable and secure.