Reactive web security configuration for Spring WebFlux applications using the ServerHttpSecurity builder. Provides reactive equivalents of servlet security features using Project Reactor (Mono/Flux).
Enable Spring Security for reactive WebFlux applications.
package org.springframework.security.config.annotation.web.reactive;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import({ReactiveAuthenticationManagerConfiguration.class,
ServerHttpSecurityConfiguration.class,
WebFluxSecurityConfiguration.class,
ServerOAuth2SecurityConfiguration.class})
public @interface EnableWebFluxSecurity {
}Usage:
@Configuration
@EnableWebFluxSecurity
public class ReactiveSecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// Configure security
return http.build();
}
}Main builder for configuring reactive web security.
package org.springframework.security.config.web.server;
public class ServerHttpSecurity {
// Authorization
public ServerHttpSecurity authorizeExchange(
Customizer<AuthorizeExchangeSpec> authorizeExchangeCustomizer
);
// Authentication
public ServerHttpSecurity formLogin(
Customizer<FormLoginSpec> formLoginCustomizer
);
public ServerHttpSecurity httpBasic(
Customizer<HttpBasicSpec> httpBasicCustomizer
);
public ServerHttpSecurity oauth2Login(
Customizer<OAuth2LoginSpec> oauth2LoginCustomizer
);
public ServerHttpSecurity oauth2Client(
Customizer<OAuth2ClientSpec> oauth2ClientCustomizer
);
public ServerHttpSecurity oauth2ResourceServer(
Customizer<OAuth2ResourceServerSpec> oauth2ResourceServerCustomizer
);
public ServerHttpSecurity x509(
Customizer<X509Spec> x509Customizer
);
public ServerHttpSecurity anonymous(
Customizer<AnonymousSpec> anonymousCustomizer
);
// Security Features
public ServerHttpSecurity csrf(
Customizer<CsrfSpec> csrfCustomizer
);
public ServerHttpSecurity cors(
Customizer<CorsSpec> corsCustomizer
);
public ServerHttpSecurity headers(
Customizer<HeaderSpec> headersCustomizer
);
public ServerHttpSecurity exceptionHandling(
Customizer<ExceptionHandlingSpec> exceptionHandlingCustomizer
);
public ServerHttpSecurity logout(
Customizer<LogoutSpec> logoutCustomizer
);
public ServerHttpSecurity requestCache(
Customizer<RequestCacheSpec> requestCacheCustomizer
);
public ServerHttpSecurity sessionManagement(
Customizer<SessionManagementSpec> sessionManagementCustomizer
);
public ServerHttpSecurity oidcLogout(
Customizer<OidcLogoutSpec> oidcLogoutCustomizer
);
public ServerHttpSecurity passwordManagement(
Customizer<PasswordManagementSpec> passwordManagementCustomizer
);
public ServerHttpSecurity oneTimeTokenLogin(
Customizer<OneTimeTokenLoginSpec> oneTimeTokenLoginCustomizer
);
// Filter Management
public ServerHttpSecurity addFilterAt(
WebFilter webFilter,
SecurityWebFiltersOrder order
);
public ServerHttpSecurity addFilterBefore(
WebFilter webFilter,
SecurityWebFiltersOrder order
);
public ServerHttpSecurity addFilterAfter(
WebFilter webFilter,
SecurityWebFiltersOrder order
);
// Authentication Configuration
public ServerHttpSecurity authenticationManager(
ReactiveAuthenticationManager authenticationManager
);
// Request Matching
public ServerHttpSecurity securityMatcher(ServerWebExchangeMatcher matcher);
// Build
public SecurityWebFilterChain build();
}Configure URL-based access control for reactive applications.
public class AuthorizeExchangeSpec {
public Access pathMatchers(HttpMethod method, String... patterns);
public Access pathMatchers(String... patterns);
public Access matchers(ServerWebExchangeMatcher... matchers);
public Access anyExchange();
public final class Access {
public AuthorizeExchangeSpec permitAll();
public AuthorizeExchangeSpec denyAll();
public AuthorizeExchangeSpec authenticated();
public AuthorizeExchangeSpec hasRole(String role);
public AuthorizeExchangeSpec hasAnyRole(String... roles);
public AuthorizeExchangeSpec hasAuthority(String authority);
public AuthorizeExchangeSpec hasAnyAuthority(String... authorities);
public AuthorizeExchangeSpec access(ReactiveAuthorizationManager<AuthorizationContext> manager);
}
}Usage Examples:
http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/public/**").permitAll()
.pathMatchers("/admin/**").hasRole("ADMIN")
.pathMatchers(HttpMethod.GET, "/api/**").hasAuthority("READ")
.pathMatchers(HttpMethod.POST, "/api/**").hasAuthority("WRITE")
.anyExchange().authenticated()
);public class FormLoginSpec {
public FormLoginSpec loginPage(String loginPage);
public FormLoginSpec authenticationManager(ReactiveAuthenticationManager authenticationManager);
public FormLoginSpec authenticationSuccessHandler(ServerAuthenticationSuccessHandler handler);
public FormLoginSpec authenticationFailureHandler(ServerAuthenticationFailureHandler handler);
public FormLoginSpec authenticationEntryPoint(ServerAuthenticationEntryPoint entryPoint);
public FormLoginSpec requiresAuthenticationMatcher(ServerWebExchangeMatcher matcher);
}public class HttpBasicSpec {
public HttpBasicSpec authenticationManager(ReactiveAuthenticationManager authenticationManager);
public HttpBasicSpec authenticationEntryPoint(ServerAuthenticationEntryPoint entryPoint);
}public class CsrfSpec {
public CsrfSpec csrfTokenRepository(ServerCsrfTokenRepository csrfTokenRepository);
public CsrfSpec requireCsrfProtectionMatcher(ServerWebExchangeMatcher matcher);
public CsrfSpec csrfTokenRequestHandler(ServerCsrfTokenRequestHandler requestHandler);
public ServerHttpSecurity disable();
}public class CorsSpec {
public CorsSpec configurationSource(CorsConfigurationSource source);
public ServerHttpSecurity disable();
}public class SessionManagementSpec {
public SessionManagementSpec sessionConcurrency(
Customizer<SessionConcurrency> concurrencyCustomizer
);
public final class SessionConcurrency {
public SessionConcurrency maximumSessions(SessionLimit sessionLimit);
public SessionConcurrency invalidSessionStrategy(InvalidSessionServerAuthenticationSuccessHandler strategy);
}
}Usage Examples:
// Reactive security configuration
@Configuration
@EnableWebFluxSecurity
public class ReactiveSecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/", "/public/**").permitAll()
.pathMatchers("/admin/**").hasRole("ADMIN")
.anyExchange().authenticated()
)
.formLogin(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults())
.csrf(csrf -> csrf.disable())
.cors(Customizer.withDefaults());
return http.build();
}
@Bean
public ReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withUsername("user")
.password("{noop}password")
.roles("USER")
.build();
return new MapReactiveUserDetailsService(user);
}
}
// OAuth2 Resource Server (JWT)
http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/api/**").hasAuthority("SCOPE_read")
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
// OAuth2 Login
http
.authorizeExchange(exchanges -> exchanges
.anyExchange().authenticated()
)
.oauth2Login(Customizer.withDefaults());// Security Web Filters Order (for filter ordering)
public enum SecurityWebFiltersOrder {
FIRST,
HTTP_HEADERS_WRITER,
HTTP_BASIC,
FORM_LOGIN,
AUTHENTICATION,
ANONYMOUS_AUTHENTICATION,
OAUTH2_AUTHORIZATION_CODE,
LOGIN_PAGE_GENERATING,
LOGOUT_PAGE_GENERATING,
CORS,
CSRF,
REACTOR_CONTEXT,
EXCEPTION_TRANSLATION,
AUTHORIZATION,
LAST
}