如何加快SpringBoot 2.0基本身份验证?

Phi*_*e A 5 spring-security spring-boot

我最近将Spring Boot应用程序从v1.5更新到了v2.0.3。这是一个应用程序,其方法公开为REST端点,并通过基本HTTP身份验证进行保护。用户名和密码硬编码在应用程序加载的属性文件中。

自更新以来,响应时间增加了近200毫秒,而处理请求的时间的98%花费在BasicAuthenticationFilter.doFilter()中。

新的文物交易明细

更具体地说,花费时间对请求中的密码进行编码,以将其与配置提供的密码进行比较。

visualvm详细信息

这是SecurityConfig类的摘录:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

为了验证这是由于Spring Boot更新引起的,我在本地恢复了更改并运行了一些测试。响应时间除以4。

我已经尝试了一些方法,但是它们都没有改善响应时间:

我可以做些什么来加快身份验证筛选器的速度吗?

Sel*_*dek 6

bcrypt 是一个故意减慢的哈希函数。虽然这种缓慢的速度在密码哈希方面听起来很矛盾,但这并不是因为好人和坏人都减慢了速度。如今,大多数密码攻击都是暴力字典攻击的某种变体。这意味着攻击者会像好人一样通过散列来尝试很多很多候选密码。如果匹配,则密码已被破解。

然而,如果坏人每次尝试的速度都减慢,那么当进行数百万次尝试时,速度就会被放大,通常会达到挫败攻击的程度。然而,好人在尝试登录时可能不会注意到。

因此,基本上,brypt 编码器内额外的 200ms 处理时间是故意的,并且是安全的一部分 通过加速(如使用缓存),您会降低应用程序的安全级别。

- - 编辑:

顺便提一句。仍然有一种快速安全的方法来评估密码匹配:使用一些缓存服务(如此处的其他答案),但仅将匹配的值存储在缓存中!这样,如果用户提供了有效的密码,则只会在第一次时缓慢地评估该密码,但其所有后续登录都会很快。但如果攻击者尝试使用暴力破解,那么他的所有尝试都将花费 200 毫秒。


Phi*_*e A 0

事实上,一种解决方案是使用另一种密码编码器,例如在 SecurityConfig 类中:

@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService())
        .passwordEncoder(passwordEncoder());
}

@Bean
public UserDetailsService userDetailsService() {
    PasswordEncoder encoder = passwordEncoder();
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    UserDetails user = User.withUsername(userName).password(encoder.encode(password)).roles(userRoles).build();
    manager.createUser(user);
    return manager;
}

private PasswordEncoder passwordEncoder() {
    // return a fast password encoder
}
Run Code Online (Sandbox Code Playgroud)

现在,使用哪种加密算法是另一个问题。虽然 bcrypt 似乎是一个安全的选择,但我想知道是否有必要考虑到密码存储在内存中,因此难以访问。

也可以看看