我有一个REST api应用程序,其中凭据作为哈希存储在数据库表中。另外,我还有另一个管理第一个应用程序凭据的应用程序。我在两个应用程序中都生成了一个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。REST api应用程序的bcrypt无法匹配在管理员应用程序中生成的bcrypt哈希。我认为bcrypt生成的随机盐也取决于它初始化的上下文?
我们使用基本身份验证进行测试,并使用管理应用程序生成的正确密码,然后将其作为哈希存储在数据库中。
两个应用程序共享同一数据库,但彼此独立。
在两个应用程序中都可以使用bcrypt还是在两个应用程序之间交换密码的最佳方法是什么?
答案 0 :(得分:0)
您无需在应用程序之间共享BCrypt编码器。
BCryptPasswordEncoder
哈希的结构是以下内容的串联:
进行身份验证时,基本上可以从用户请求中获取用户名和密码,根据提供的用户名从数据库中获取用户,从哈希密码中提取哈希算法,迭代次数和盐。数据库,根据该数据对请求密码进行哈希处理,然后比较哈希值。对用户进行身份验证时不涉及盐生成。仅当您创建或更新密码时才会生成Salt。
请注意,哈希算法,迭代次数和盐提取是通过matches
中的BCryptPasswordEncoder
方法在后台完成的(将哈希密码和普通密码作为参数)。
我的最佳猜测是,您没有使用matches
中的BCryptPasswordEncoder
方法将请求密码与数据库密码进行比较,而是重新哈希了请求密码并将结果哈希与数据库哈希进行比较。这将不起作用,因为编码方法将生成一个新的盐,该盐将对密码进行哈希处理,从而导致不同的哈希值。