Spring 安全 - 如何在两个应用程序之间共享 bcrypt?

Spring Securty - How to share bcrypt between two applications?

我有一个 REST api 应用程序,其中凭据作为哈希存储在数据库 table 中。此外,我还有另一个应用程序管理第一个应用程序的凭据。我在两个应用程序中都生成了一个 DelagtingPasswordEncoder。

@Bean
public PasswordEncoder delegatingPasswordEncoder() {
    PasswordEncoder defaultEncoder = NoOpPasswordEncoder.getInstance();
    Map<String, PasswordEncoder> encoders = new HashMap<>();
    encoders.put("bcrypt", new BCryptPasswordEncoder());
    encoders.put("scrypt", new SCryptPasswordEncoder());

    DelegatingPasswordEncoder passworEncoder = new DelegatingPasswordEncoder("bcrypt", encoders);
    passworEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder);

    return passworEncoder;
}

当我尝试使用管理应用程序生成的凭据在 REST api 上进行身份验证时,我收到了未经授权的 401。管理员应用程序中生成的 bcrypt 哈希无法与 REST 的 bcrypt 匹配api 申请。我假设 bcrypt 生成的随机盐也取决于它初始化的上下文?

我们使用 Basic Auth 进行测试,使用管理应用程序生成的正确密码,然后将其作为哈希存储在数据库中。

两个应用程序共享同一个数据库,但在其他方面相互独立。

是否可以在两个应用程序中使用 bcrypt,或者在两个应用程序之间交换密码的最佳方式是什么?

您不需要在应用程序之间共享 BCrypt 编码器。

BCryptPasswordEncoder 哈希的结构是以下内容的串联:

  • 哈希算法
  • 哈希迭代次数
  • 哈希盐+密码

当你进行身份验证时,你基本上从用户请求中获取用户名和密码,根据提供的用户名从数据库中获取用户,从哈希密码中提取哈希算法、迭代次数和盐分从数据库中,根据该数据散列请求密码,然后比较散列值。当您对用户进行身份验证时,不涉及生成盐。只有在您创建或更新密码时才会生成盐。

请注意,哈希算法、迭代次数和盐提取是通过 BCryptPasswordEncoder 中的 matches 方法在后台完成的(该方法将哈希密码和普通密码作为参数)。

我最好的猜测是您没有使用 BCryptPasswordEncoder 中的 matches 方法将请求密码与数据库密码进行比较,而是重新哈希请求密码并将结果哈希与数据库进行比较哈希。这是行不通的,因为编码方法将生成一个新的盐,用于对密码进行哈希处理,从而产生不同的哈希值。