I recently updated a Spring Boot application from v1.5 to v2.0.3. It's an application with methods exposed as REST endpoints and secured by Basic HTTP authentication. The usernames and passwords are hardcoded in a properties file loaded by the application.
Since the update, the response time increased by almost 200ms, and 98% of the time processing a request is spent in BasicAuthenticationFilter.doFilter().
More specifically, time is spent encoding the password in the request to compare it with the password provided by configuration.
Here's an extract of the SecurityConfig class:
@EnableWebSecurity
@PropertySource("classpath:auth/auth.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${user.name}")
private String userName;
@Value("${user.password}")
private String userPassword;
@Value("${user.roles}")
private String[] userRoles;
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
UserDetails user = User.withUsername(userName).password(encoder.encode(userPassword)).roles(userRoles).build();
auth.inMemoryAuthentication().withUser(user);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
//make sure that the basic authentication header is always required
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//set the correct authentication entry point to make sure the 401 response is in JSON format
http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint());
//enable http basic authentication
http.httpBasic();
//make sure authentication is required for all requests except /actuator/info
http.authorizeRequests().antMatchers("/actuator/info").permitAll().anyRequest().authenticated();
http.authorizeRequests().antMatchers("/actuator/**").hasAnyRole("MONITOR", "ACTUATOR");
//disable the form login since this is a REST API
http.formLogin().disable();
//disable csrf since this is a REST API
http.csrf().disable();
}
}
To verify that it was due to the Spring Boot update, I locally reverted the changes and ran some tests. The response time was divided by 4.
I've tried a few things already but none of them improved the response time:
- Disable oAuth (and cors) login as it seems to be slow as well https://github.com/spring-projects/spring-security-oauth/issues/943
- Provide a UserDetailsService bean instead of configuring the AuthenticationManagerBuilder https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Security-2.0#changing-the-username-and-password
Can I do anything to speed up the authentication filter?