How to Secure Spring WebFlux Applications with Reactive Security Configurations

This guide walks through setting up Spring Security for WebFlux, covering Maven dependencies, reactive security beans, password encoding, filter chain rules, functional routing, and method‑level authorization with complete code examples for a Spring Boot 2.5.8 project.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Secure Spring WebFlux Applications with Reactive Security Configurations

Introduction

Spring Security’s support for WebFlux relies on WebFilter, functioning the same way as in traditional Spring WebFlux applications. In contrast, Spring MVC uses Filter.

Dependency Management

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

Security Configuration

@Configuration
@EnableReactiveMethodSecurity
public class WebfluxSecurityConfig {
  @Bean
  public MapReactiveUserDetailsService userDetailsService() {
    // configure an in‑memory user
    UserDetails user = new Users();
    return new MapReactiveUserDetailsService(user);
  }

  // password encoder
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new PasswordEncoder() {
      @Override
      public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return rawPassword.equals(encodedPassword);
      }
      @Override
      public String encode(CharSequence rawPassword) {
        return rawPassword.toString();
      }
    };
  }

  @Bean
  public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.csrf(csrf -> csrf.disable());
    http.authorizeExchange(exchanges -> {
      exchanges.pathMatchers(HttpMethod.GET, "/css/**", "/resources/**").permitAll();
      exchanges.pathMatchers("/users/**").hasRole("ADMIN");
      exchanges.anyExchange().authenticated();
    });
    // default login form
    http.formLogin();
    http.exceptionHandling(exceptionHandling -> {
      exceptionHandling.accessDeniedHandler((exchange, denied) -> {
        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap("Access Denied".getBytes());
        return exchange.getResponse().writeAndFlushWith(Mono.just(Mono.just(buffer)));
      });
    });
    return http.build();
  }
}

Router Configuration

@Configuration
public class RouterConfig {
  @Bean
  public RouterFunction<ServerResponse> usersRouter() {
    return RouterFunctions.route()
      .GET("/users/{id}", request -> {
        System.out.println("查询:" + request.pathVariable("id"));
        return ServerResponse.ok().bodyValue(new Users());
      })
      .build();
  }
}

Method‑Level Security

@RestController
@RequestMapping("/antUsers")
public class UsersController {

  @GetMapping("/index")
  @PreAuthorize("hasRole('10000')")
  public Mono<String> index() {
    return Mono.just("success");
  }
}

End of tutorial.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaConfigurationSpring Bootsecurityreactive
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.