使用 Spring 的 security 3.1.x 需要一些帮助或指导。
我在 MySql 数据库中存储了一个加密的密码。哪个密码被定义为 varchar(60) 列。
第一次运行 Web 应用程序时,我使用以下代码片段生成了密码:
String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
然后我将字符串编码密码粘贴到数据库列中。我将代码保存在我的身份验证管理器中(代码如下),并将编码密码记录到服务器日志中。
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="usersDAO">
<security:password-encoder ref="encoder" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
我的问题是身份验证失败并出现异常:BCryptPasswordEncoder.matches() 运行时凭据错误。存储的密码与表单输入生成的哈希不匹配。使用了在初始哈希生成中使用的相同文本密码。
每次我输入相同的文本重新运行登录时,记录的编码密码都是不同的。调试我可以看到从数据库中正确返回实体的位置,所以我认为这不是问题。在我看来,这个问题似乎是我没有正确执行/设置某些内容,以便在每次输入文本密码时生成相同的哈希。
编辑:添加用户DAO。
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UsersDAO extends Dao<Users>, UserDetailsService
{
Users getByUsername(String username);
}
编辑:添加实现。
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Repository("usersDAO")
public class UsersDAO_DB extends AbstractHibernateDao<Users> implements UsersDAO
{
final Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public Users getByUsername(String username)
{
String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
log.debug("HELLOZ ----> " + encodedPassword);
notNull(username, "username can't be null");
return (Users) getSession()
.getNamedQuery("users.byUsername")
.setParameter("username", username)
.uniqueResult();
}
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
notNull(username, "username can't be null");
Users users = getByUsername(username);
if (users == null) {
throw new UsernameNotFoundException("No user with username " + username);
}
return users;
}
@Override
public void create(Users t)
{
// TODO Auto-generated method stub
}
@Override
public void update(Users t)
{
// TODO Auto-generated method stub
}
@Override
public void delete(Users t)
{
// TODO Auto-generated method stub
}
}
有任何想法吗?