【问题标题】:Spring Security Custom Authentication and Password EncodingSpring Security 自定义身份验证和密码编码
【发布时间】:2011-12-01 07:29:18
【问题描述】:

那里有教程吗,或者有人有关于如何使用 Spring-Security 执行以下操作的指示吗?

任务:

我需要从我的数据库中获取用于验证用户名的 salt,并使用它来加密提供的密码(来自登录页面),以将其与存储的加密密码(也就是验证用户)进行比较。

其他信息:

我使用自定义数据库结构。 UserDetails 对象是通过自定义 UserDetailsService 创建的,而 UserDetailsService 又使用自定义 DAOProvider 从数据库中获取信息。

到目前为止我的security.xml 文件:

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
    </authentication-provider>
</authentication-manager>

现在我想我需要

        <password-encoder hash="sha" />

但还有什么?如何告诉 Spring Security 使用数据库提供的盐来编码密码?


编辑

我发现This SO 的帖子提供了丰富的信息,但还不够:如果我在我的 xml 中定义一个盐源以供密码编码器使用,如下所示:

        <password-encoder ref="passwordEncoder">                
            <salt-source ref="saltSource"/>
        </password-encoder>

我必须编写一个自定义 SaltSource 才能使用我的自定义盐。但这在UserDetails 对象中找不到。所以...

备选方案 1:

我可以使用自定义的 UserDetails 实现,它可能具有 salt 属性吗?

<beans:bean id="saltSource" class="path.to.MySaltSource"
    p:userPropertyToUse="salt"/>

@Service("userDetailsService") 
public class UserDetailsServiceImpl implements UserDetailsService {
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {

        // ...
        return buildUserFromAccount(account);
    }

    @Transactional(readOnly = true)

    UserDetailsImpl buildUserFromAccount(Account account){

        // ... build User object that contains salt property
}

自定义用户类:

public class UserDetailsImpl extends User{

    // ...

    private String salt;

    public String getSalt() { return salt; }

    public void setSalt(String salt) { this.salt = salt; }
}

security.xml:

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha">                
        <salt-source ref="saltSource"/>
    </password-encoder>
    </authentication-provider>
</authentication-manager>

<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/>


备选方案 2:

否则我必须将我的 accountDAO 注入 SaltSource 以从数据库中提取给定 userName 的盐。

但是:Spring Security 如何调用SaltSource?始终使用saltSource.getSalt(userDetails)

然后我只需要确保我的SaltSource 在我的accountDAO 上使用userDetails.accountName 来检索盐。


编辑2:

刚刚得知我的方法是.. legacy.. :( 所以我想我会使用StandardPasswordEncoder(我仍然需要弄清楚如何使用它)。

顺便说一句:我使用扩展 User 类的自定义 UserDetails 类实现了第一个选项,并且只添加了一个 salt 属性,然后将其作为 userPropertyToUse 传递给 SaltSource,就像在编辑 1 中提到的 SO 帖子中提出的那样...


编辑 3:

StandardPasswordEncoder 刚刚开始工作,所以我将在此处留下一些提示:

使用 StandardPasswordEncoder 进行身份验证:

<beans:bean id="encoder" 
    class="org.springframework.security.crypto.password.StandardPasswordEncoder">
</beans:bean>


<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder ref="encoder" />         
    </authentication-provider>
</authentication-manager>

这需要3.1.0.RC版本的spring-security-crypto模块?据我所知。找不到任何具有 3.0 的存储库。版本(即使某处列出的版本包括 3.0.6 等)。此外,文档还谈到了 spring security 3.1,所以我想,我会继续这样做。

创建用户时(对我来说只有管理员可以这样做),我只使用

        StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        String result = encoder.encode(password);

我已经完成了。

Spring security 会随机创建一个 salt 并将其添加到密码字符串中,然后再将其存储到数据库中,因此 不再需要 salt 列

然而,也可以提供一个全局盐作为构造函数参数 (new StandardPasswordEncoder("12345");),但我不知道如何设置我的安全配置以从 bean 中检索该值,而不是使用 @987654344 提供静态字符串@。不过我也不知道到底需要多少。

【问题讨论】:

    标签: authentication passwords spring-security salt


    【解决方案1】:

    我会将此标记为已回答,因为我解决了我的问题并且没有给出其他 cmets 或答案:

    编辑 1 - 备选方案 1 回答了原始问题

    但是我必须知道自定义密码加盐是一种遗留方法,在 Spring Security 3.1 中不再需要,正如我在

    中描述的那样

    编辑 3 我在其中留下了一些关于如何使用 StandardPasswordEncoder 用于与密码一起存储的自动 Salts 的指示。

    【讨论】:

    • 你的帖子真的帮助了我,我遇到了非常相似的问题。 +1 自我解决 ^^
    • 我建议使用 BCryptPasswordEncoder 而不是 StandardPasswordEncoder。 BCryptPasswordEncoder 在安全性和与其他语言的互操作性方面都是更好的选择
    【解决方案2】:

    为了它的价值,我写了这篇博文,详细说明了您所描述的内容: http://rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords

    【讨论】:

      【解决方案3】:

      要从 bean 中检索全局盐,请使用 Spring 表达式语言或 SpEL。

      <beans:bean id="encoder" 
              class="org.springframework.security.crypto.password.StandardPasswordEncoder">
          <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/>
      </beans:bean>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-20
        • 2014-12-13
        • 2016-09-05
        • 2012-03-07
        • 2021-12-05
        • 2016-08-05
        • 2020-12-05
        • 2015-04-27
        相关资源
        最近更新 更多