【发布时间】:2017-04-25 15:28:06
【问题描述】:
注册新用户后,数据库中生成的哈希密码与用户输入的密码不匹配,以便进行身份验证。原始密码相同,但散列版本不同。我想知道如何让这两者相互匹配以进行正确的身份验证?我使用 Spring 4.3.2.RELEASE 和 4.2.0.RELEASE 来保证安全性。
我还有一个警告:
WARN SpringSecurityCoreVersion:78 - **** You are advised to use Spring 4.3.4.RELEASE or later with this version. You are running: 4.3.0.RELEASE
也许这会导致某种问题。
config.xml:
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<security:password-encoder ref="encoder"/>
</security:authentication-provider>
</security:authentication-manager>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService" />
<property name="hideUserNotFoundExceptions" value="false" />
<property name="passwordEncoder" ref="encoder" />
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<ref bean="daoAuthenticationProvider" />
</constructor-arg>
</bean>
UserEntity.java:
public void setPassword(String password) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
this.password = passwordEncoder.encode(password);
}
UserAuthenticationProviderService.java:
public boolean processUserAuthentication(UserEntity user) {
try {
Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
return true;
} catch(AuthenticationException e) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Catched Error!"));
return false;
}
}
编辑:已解决。
正如 Shaun 所说,问题在于实体类中的编码。将编码移动到用户创建位置后一切正常,因为编码现在只出现在用户创建过程中。谢谢!
【问题讨论】:
-
您将名称空间配置和普通 Java bean 用于身份验证管理器。您应该选择其中之一。另外,你的问题不是很清楚。 “散列版本不同”是什么意思 - 你怎么知道?你在比较什么,在哪里比较?数据库中的值是否可识别为 bcrypt 哈希?发布一个示例并使用实际(测试)数据说明您的意思。
-
用密码注册后:“superman”,密码在数据库中保存为:“$2a$10$lwRt//HRsibkzHQzECHxi.E2hacnQve3JTZkxlrwlvVZ1S0w1DKO6”就可以了。但在那之后,当应用程序尝试自动登录时,数据库中的密码更改为:“$2a$10$19Z.a2KhDELFMJ55VhxQtOvaZsO0n8q2VLXUqBpxsmHfj3j3NkQjq”并保持这种状态。看起来像是在同一次运行中用错误的密码更新了正确的密码,但现在我不知道原因。
-
更新:不会一直这样。在任何尝试登录后它正在更新(更新仍然不匹配)
-
Spring Security 不会更新您的数据库 - 您必须在其他地方进行更新。您应该调试这些更改并找出它们来自哪里以及正在散列的值是什么。实体代码令人困惑。如果那是数据库实体,为什么要使用其中的密码进行身份验证?看起来您正在获取一个已经散列的密码并将其传递给 AuthenticationManager,它将在检查期间再次散列它(这显然会失败)。
标签: java spring spring-mvc authentication spring-security