我已使用spring security实现了更改密码功能,但((UserDetails)principal).getPassword())为登录用户返回null .
如果我没记错的话,过去常常在3.0中使用 . 这是在3.1中更改,以便无法检索登录用户的当前密码?
在下面的代码中,我正在检查从网页输入的用户密码中的当前密码 . 然后我检查登录用户的密码是否与输入的密码匹配 . 如果是,那么我想设置oldPasswordMatchNewPassword = true .
我该如何实现此功能?
@RequestMapping(value = "/account/changePassword.do", method = RequestMethod.POST)
public String submitChangePasswordPage(
@RequestParam("oldpassword") String oldPassword,
@RequestParam("password") String newPassword) {
Object principal = SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
String username = principal.toString();
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
System.out.println("username: " + username);
System.out.println("password: "
+ ((UserDetails) principal).getPassword());
if (((UserDetails) principal).getPassword() != null) {
if (((UserDetails) principal).getPassword().equals(oldPassword)) {
oldPasswordMatchNewPassword = true;
}
}
}
if (oldPasswordMatchNewPassword == true) {
logger.info("Old password matches new password. Password will be updated.");
changePasswordDao.changePassword(username, newPassword);
SecurityContextHolder.clearContext();
return "redirect:home.do";
} else {
logger.info("Old password did not match new password. Password will be not be updated.");
return null;
}
}
我放了几个sysout(),以便我可以看到返回的值 . 对于((UserDetails)principal).getUsername()我可以看到正确的登录用户 . ((UserDetails)principal).getPassword()它返回null .
我如何得到((UserDetails)principal).getPassword()这个值?
提前致谢!
3 回答
我使用这段代码(erase-credentials =“false”)来解决这个问题 . 我不知道这是否是一个优雅的解决方案,但它解决了我的问题:
是的,3.1版本已经改变了 . 默认情况下,在成功进行身份验证后会清除凭据 . 您可以在
ProviderManager
上将eraseCredentialsAfterAuthentication
设置为false以防止这种情况发生 . 详情请见:http://static.springsource.org/spring-security/site/docs/3.2.x/reference/core-services.html#core-services-erasing-credentials由于在用户通过身份验证后密码未保留在内存中(通常是一件好事),因此您需要显式重新加载密码才能使用它 . 另一种更灵活的策略是注入
AuthenticationManager
的实例并直接使用它:这样你就不会以纯文本形式存储密码 . 它们应该使用bcrypt or something similar进行哈希处理 .