Spring Security:DB和applicationContext中的密码编码

ser*_*nni 34 database passwords encoding config spring-security

有config(applicationContext-security.xml):

<authentication-manager alias="authenticationManager">
    <authentication-provider>
    <password-encoder hash="sha"/>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>
Run Code Online (Sandbox Code Playgroud)

从另一边有我的dataSource(这是JdbcDaoImpl)的SQL :

...
    public static final String DEF_USERS_BY_USERNAME_QUERY =
            "select username,password,enabled " +
            "from users " +
            "where username = ?";
...
Run Code Online (Sandbox Code Playgroud)

现在有关sha于此代码的消息,因此从标准Spring Security users表中选择的密码未编码.

也许,我应该在我的hibernate映射配置中shapassword列提供一些属性:

<class name="model.UserDetails" table="users">
    <id name="id">
        <generator class="increment"/>
    </id>
    <property name="username" column="username"/>
    <property name="password" column="password"/>
    <property name="enabled" column="enabled"/>
    <property name="mail" column="mail"/>
    <property name="city" column="city"/>
    <property name="confirmed" column="confirmed"/>
    <property name="confirmationCode" column="confirmation_code"/>

    <set name="authorities" cascade="all" inverse="true">
        <key column="id" not-null="true"/>
        <one-to-many class="model.Authority"/>
    </set>

</class>
Run Code Online (Sandbox Code Playgroud)

现在密码保存到DB,但应编码.

如何将applicationContext配置和数据库查询的朋友密码编码相同?

Sha*_*eep 78

如果您自己选择散列系统,而不是使用已包含散列密码的现有数据库构建应用程序,则应确保散列算法也使用盐.不要只使用简单的摘要.

一个很好的选择是bcrypt,我们现在通过BCryptPasswordEncoder(使用jBCrypt实现)直接在Spring Security 3.1中支持.这会自动生成一个salt,并将其与单个String中的哈希值连接起来.

一些数据库内置支持散列(例如Postgres).否则,您需要在将密码传递给JDBC之前自己哈希密码:

String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
Run Code Online (Sandbox Code Playgroud)

这就是在创建用户时对密码进行编码所需要做的全部工作.

对于身份验证,您可以使用以下内容:

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

<bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <property name="userDetailsService" ref="yourJdbcUserService" />
  <property name="passwordEncoder" ref="encoder" />
</bean>
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用像bcrypt这样的东西,那么它会自动为您处理,所以没有任何挑战:-).您不必自己处理盐. (4认同)
  • 我想知道BCryptPasswordEncoder是如何工作的.它是为所有密码生成一个盐还是为每个密码生成一个单独的盐?如果是这样,它在哪里存储用户盐? (2认同)

fal*_*ker 8

对接受的答案稍作解释.希望它可以帮助某人.

在将密码放入数据库之前自己哈希密码:

String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
Run Code Online (Sandbox Code Playgroud)

将BCryptPasswordEncoder bean添加到security-config.xml

将passwordEncoder作为属性添加到Authentication Provider类.自动装配或提供setter和getter方法.

@AutoWired
private BCryptPasswordEncoder passwordEncoder;
Run Code Online (Sandbox Code Playgroud)

在您认证用户登录时获取该属性

<bean id="dbAuthenticationProvider" class="mypackage.auth.spring.DBAuthenticationProvider" >
    <property name="dataSource" ref="routingDataSource"></property>
    <property name="passwordEncoder" ref="encoder" />
    <property name="passwordQuery"
        value="select password as password from tbl where username=:username">
    </property> 
</bean>
Run Code Online (Sandbox Code Playgroud)

并且在身份验证类中匹配两个密码

 new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb)
Run Code Online (Sandbox Code Playgroud)


fal*_*lla 5

使用Spring Security 3.1,试试这个:

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="service">
        <password-encoder hash="sha"/>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>

<beans:bean id="dataSource" ...>
    ...
</beans:bean>

<beans:bean id="service" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
        ...
</beans:bean>
Run Code Online (Sandbox Code Playgroud)

最新消息:authentication-provider指向serviceservice指向datasource.

编辑:在Java中,您必须使用以下内容对密码进行编码:

DigestUtils.sha(request.getParameter("password"));
Run Code Online (Sandbox Code Playgroud)

警告:小心!不要将SHAMD5混合使用!

如果设置password-encoderauthentication-providerSHA,您需要在Java中相同的方式来保持一致的编码.但是如果你在Java中使用MD5作为你发现的样本,请不要忘记将哈希值设置为"md5".DigestUtils还提供md5编码器:

DigestUtils.md5(request.getParameter("password"));
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以通过简单的方式执行applicationContext-security.xml中的操作

<authentication-manager alias="authenticationManager">
   <authentication-provider>
    <password-encoder ref="encoder"/>
    <jdbc-user-service data-source-ref="dataSource"
       users-by-username-query="
          select username,password, enabled 
          from principal where username=?" 
       authorities-by-username-query="
          select p.username, a.authority from principal p, authority a
          where p.id = a.principal_id and p.username=?" 
    />
   </authentication-provider>
</authentication-manager> 

  <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
Run Code Online (Sandbox Code Playgroud)

在Java中

public static String encodePasswordWithBCrypt(String plainPassword){
    return new BCryptPasswordEncoder().encode(plainPassword);
}
Run Code Online (Sandbox Code Playgroud)

然后测试一下

System.out.println(encodePasswordWithBCrypt("fsdfd"));
Run Code Online (Sandbox Code Playgroud)