java - 为什么 Spring boot Security Basic Authentication 很慢?

标签 java spring-boot spring-security basic-authentication bcrypt

我有一个 Spring boot 2.0.1 服务,我向其中添加了使用 BCrypt 进行散列的基本身份验证。但是这项服务在添加基本身份验证之前平均需要 400 毫秒,现在需要超过 1 秒。我正在使用用户详细信息服务,该服务在 HashMap 中查找发送的用户名并返回 UserDetails。我尝试将 BCrypt 轮次减少到 4,但这并没有太大的不同。

之前我启用了无状态身份验证,后来我禁用了它,但性能仍然很差。此服务托管在 Docker 容器中。

下面是我的安全配置。

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsService userDetailsService;

    @Autowired
    public SecurityConfig(UserDetailsServiceImpl service) {
        this.userDetailsService = service;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        Map encoders = new HashMap<>();
        encoders.put(BCRYPT_ID, new BCryptPasswordEncoder(BCRYPT_ROUNDS));
        return new DelegatingPasswordEncoder(BCRYPT_ID,encoders);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.cors()
            .and()
            .csrf().disable()
            .httpBasic();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }
}

如果我遗漏了什么,请告诉我。

更新:我运行了基准测试,看起来 BCrypt 编码器使应用程序变慢了。我找到了一些讨论 BCrypt 哈希计算是阻塞调用的 Stack Overflow 答案。

关于硬件:服务主机采用Intel Xeon E5,16GB内存。它托管 4 个 Spring boot 服务,每个服务分配 2 GB 在 Docker 容器内运行。

最佳答案

所以在搜索了很多关于 BCrypt 编码和解码之后,我终于找到了保持 spring boot 项目性能的解决方案,而没有 BCrypt 编码和解码造成的重大延迟。

所以 BCrypt 哈希算法适用于某些轮次。您在 BCrypt 编码中使用的轮数越多,您的项目将消耗更多的空间和内存来进行编码和解码(密码)。

话虽如此,我还想提一下,您在对密码进行编码时使用的轮数越多,它就会越安全。

我们大多数人会使用下面这些代码行在我们的代码中生成 bycrypt 凭证

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16); // here no of rounds is 16
String result = encoder.encode("password");
system.out.println("encoded password" + result );

此 java 代码用于生成 BCrypt 编码密码的轮数是 16,这太高了。有助于在时间、内存和安全性之间取得平衡的标准轮数是 10。

所以如果我们必须改变下面BCrypt Encoding中的轮数是你需要设置的

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);

当我使用 16 轮时,我用了 6 秒来访问具有基本身份验证的服务(编码和解码 BCrypt 密码平均需要 3 到 4 秒)

当我使用 10 发子弹时,我能够以平均 1 到 1.5 秒的时间击中服务

没有您应该选择的标准回合数。您应该在您的应用程序中使用性能方面可以容忍的最大轮数。轮数是一个减速因素,你使用它的基础是在正常使用情况下,这样的减速对你的影响可以忽略不计(用户不会看到它,额外的CPU成本并不意味着购买更大的服务器,并且很快)。这在很大程度上取决于操作环境:涉及哪些机器,每秒有多少用户身份验证......因此没有一刀切的响应。

关于java - 为什么 Spring boot Security Basic Authentication 很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51777464/

相关文章:

java - Spring JPA 存储库访问对象集合中的字段

java - 如何使用参数 @link 编写 javadoc @deprecated 方法

java 。 Selenium 。 Chrome 驱动程序。如何启用和禁用扩展?

spring-boot - spring boot 甚至可以直接使用JdbcTemplate 显示sql

java - 无法使用spring boot连接mysql数据库错误HTTP Status 404请求的资源不可用

java - 健康端点仅显示 "status: up"并且不显示敏感信息

java - 同一应用程序中的 OAuth2 客户端和资源服务器

java - GWT AsyncCallback 不填充静态成员

java - getPrincipal() 方法返回用户名而不是 UserDetails

java - 确保@Controller 不一致