Describe the bug When configuring a Spring Webflux application to use Spring Security to protect APIS with Basic Authentication, the performance is seriously affected.
To Reproduce
Spring WebFlux versión: 5.3.1 Spring Security: 5.4.1 Project Reactor: 3.4.0
- Define an Api Controller:
@RestController
public class ApiController {
@GetMapping("/api/test")
public Mono<String> getTest(){
return Mono.delay(Duration.ofMillis(400)) //Simulating external request
.thenReturn("Test");
}
}
- Protect the routes with Sprint Security:
@Configuration
@EnableWebFluxSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
return http.csrf().disable()
.authorizeExchange()
.pathMatchers("/api/movements/health")
.permitAll()
.anyExchange()
.authenticated()
.and()
.httpBasic()
.and()
.formLogin().disable()
.build();
}
}
- Do a performance test:
The orange line is the behavior without Spring Security and the blue line with Spring Security. You can see that the latency increase a lot with the use of Spring Security, producing a serious effect on the throughput.
Expected behavior That there isn't such a big impact on performance with the use of Spring Security on webflux.
What do you think ?
Best regards, Daniel Rico
Comment From: eleftherias
This is by design.
Spring Security leverages an adaptive one-way function to store the password. These are intentionally resource intensive, which means validating a username and password for every request will degrade performance of an application significantly. There is nothing Spring Security (or any other library) can do to speed up the validation of the password since security is gained by making the validation resource intensive.
Rather than using HTTP Basic Authentication, I encourage you to exchange the long term credentials (i.e. username and password) for a short term credential (i.e. session, OAuth Token, etc). The short term credential can be validated quickly without any loss in security.
There is an in-depth explanation of this in the Spring Security reference documentation.