我需要修改安全登录代码:
@Override
public User login(String username, String password, Boolean rememberMe) {
log.info("Logging in username="+username);
UsernamePasswordToken token;
String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
log.info("Hashed password=" + hashed);
token = new UsernamePasswordToken(username, hashed);
// ”Remember Me” built-in, just do this:
token.setRememberMe(rememberMe);
try {
// With most of Shiro, you'll always want to make sure you're working with the currently executing user,
// referred to as the subject
Subject currentUser = SecurityUtils.getSubject();
// Authenticate
//currentUser.login(token);
User user = userDAO.fetchUserByName(username, hashed);
return user;
} catch (org.apache.shiro.authc.AuthenticationException e) {
throw new AuthenticationException("Failure in authentication");
} catch (IllegalStateException e){
throw new AuthenticationException("Application is in a illegal state");
} catch (Exception e){
throw new AuthenticationException("Some other error during login was caught.");
}
}
在DAO级别:
但是,现在,存储在数据库中的密码很简单,我只是用散列密码替换它。这里的问题是:
所以问题是如何在每次更改时存储哈希密码。
我在想的是
解决这个问题的正确方法是什么?
答案 0 :(得分:3)
BCrypt.hashpw方法不会为多次迭代返回相同的密码哈希值。
您需要使用BCrypt类的checkpw方法比较不同的哈希密码(一个是新创建的,一个是数据库中的。)
BCrypt.gensalt()在您的方法中正确使用。 只需根据用户名检索用户信息,并使用checkpw方法比较散列密码。
我希望它有所帮助。
答案 1 :(得分:3)
您应该知道hashpw()
产生的“哈希密码”不仅仅是哈希。它还包含以明文形式传递的随机生成的盐。
BCrypt.checkpw(password, storedHash)
是检查存储哈希的正确方法。该方法将从“散列密码”中检索salt,对明文密码进行散列,并将结果与storedHash
的实际散列部分进行比较。
您可以找到有关如何使用库here的详细说明。
在你的情况下,我会写这样的方法:
public User login(String username, String password) {
User user = userDAO.fetchUserByName(username);
if (!BCrypt.checkpw(password, user.getHash())
throw new AuthenticationException("Failure in authentication");
return user;
}