【问题标题】:Spring Security Password AuthenticationSpring Security 密码认证
【发布时间】:2013-11-03 12:14:18
【问题描述】:

在使用 Spring 的 security 3.1.x 时需要一些帮助或指导。

我在 MySql 数据库中存储了一个加密的密码。哪个密码被定义为 varchar(60) 列。

第一次运行 web 应用时,我使用以下代码 sn-p 生成了密码:

String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);

然后我将字符串编码密码粘贴到数据库列中。我将代码保存在我的身份验证管理器中(sn-p 后跟),并将encodedPassword 记录到服务器日志中。

<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() 运行时凭据错误。存储的密码与表单输入生成的哈希不匹配。使用了在初始哈希生成中使用的相同文本密码。

每次我输入相同的文本重新运行登录时,记录的编码密码都是不同的。调试我可以看到从数据库中正确返回实体的位置,所以我认为这不是问题。在我看来,这个问题似乎是我没有正确地做/设置一些东西,以便在每次文本时生成相同的哈希 输入密码。

编辑: 添加 usersDAO。

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

}

}

有什么想法吗?

【问题讨论】:

    标签: authentication spring-security


    【解决方案1】:

    这是遵循几个不同教程的新手错误。

    在 bean 中,我将安全编码器定义为: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

    为了生成测试密码,我使用了以下代码:

    String p = "12345";
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String encodedPassword = passwordEncoder.encode(p);
    log.debug("HELLOZ  ---->  " + encodedPassword);
    

    混合了 org.springframework.security.crypto.password.PasswordEncoder 和 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder。见上面定义passwordEncoder的代码。

    一旦我将其更改为:

    String p = "12345";
    BCryptPasswordEncoder pe= new BCryptPasswordEncoder();
    String encPassword =pe.encode(p);
    log.debug("HELLB  ---->  " + encPassword);
    

    将输出复制到我的数据库并重新测试一切正常。

    【讨论】:

      【解决方案2】:

      每次我输入相同的文本重新运行登录时,记录的编码密码都不同”。

      日志从何而来? Spring Security 不会记录传入的密码,如果你使用的是 BCrypt,它不应该在任何地方从头开始重新编码。

      听起来您可能正在自己重新编码提交的密码,可能在您未显示的usersDAO 中。

      如果没有,请发布您的完整配置和您正在谈论的日志记录输出。

      【讨论】:

      • 不,我没有对输入的纯文本密码做任何事情,而是生成一个用于打印调试语句的哈希。当我说记录密码时,这也是我所说的。
      • 哈希值总是不同的,因为 BCrypt 每次都使用不同的盐,所以这并不意味着什么。我仍然猜测您自己的 DAO 中正在发生一些事情。您发布的界面没有任何代码,因此除非您发布实际实现,否则很难说。
      • 抱歉,我不知道您需要什么。如果您需要更多,请告诉我。我收集到盐是导致密码不匹配的原因,但我只能收集到这些。
      猜你喜欢
      • 2012-02-08
      • 2011-07-26
      • 2012-09-12
      • 2012-08-15
      • 2016-08-11
      • 2017-04-25
      • 2014-02-14
      • 1970-01-01
      • 2016-11-15
      相关资源
      最近更新 更多