2011-12-15 103 views
31

有无配置(的applicationContext-security.xml文件):春季安全:DB和密码的applicationContext编码

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

从对方从我dataSource(这是JdbcDaoImpl)SQLS:

... 
    public static final String DEF_USERS_BY_USERNAME_QUERY = 
      "select username,password,enabled " + 
      "from users " + 
      "where username = ?"; 
... 

在此代码中现在有关于sha的字,因此从标准Spring Security users表中选择的密码未经过编码。

也许,我应该为password列一些sha属性在我的Hibernate映射配置此处

<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> 

现在保存到数据库为有密码,但应该进行编码。

如何将朋友applicationContext config和DB查询的密码编码相同?

回答

73

如果是自己选择一个散列系统,而不是使用已经包含散列密码现有的数据库构建应用程序,那么你应该确保你的哈希算法也使用了盐。不要只使用简单的摘要。

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

某些数据库内置了散列支持(例如Postgres)。否则,你需要将它传递给JDBC之前自己哈希密码:

String password = "plaintextPassword"; 
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String hashedPassword = passwordEncoder.encode(password); 

这就是所有你需要做的,当你创建一个用户编码密码。

对于认证,你会使用类似:

<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> 
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> 

最新消息:authentication-providerserviceservicedatasource

编辑:在Java中,你将不得不与像这样编码密码:

DigestUtils.sha(request.getParameter("password")); 

警告:小心!请勿混用SHAMD5

如果将authentication-providerpassword-encoder设置为SHA,则需要使用Java编码以保持一致。但是,如果您使用Java以MD5作为示例,则不要忘记将散列设置为“md5”。 DigestUtils还提供MD5编码器:

DigestUtils.md5(request.getParameter("password")); 
+0

是的,我知道这样做只是一个提示,但你没有对我的问题问如何提供,用户密码保存的编码,以DB – sergionni 2011-12-15 18:02:34

+1

好吧,我不知道知道你提供的意思,但要坚持,我已经使用[DigestUtils](http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html)。 – falsarella 2011-12-15 18:09:38

8

多一点的解释上公认的答案。希望它能帮助别人。

哈希把它给数据库之前,密码自己:

String password = "plaintextPassword"; 
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String hashedPassword = passwordEncoder.encode(password); 

BCryptPasswordEncoder豆添加到您的安全-config.xml中

添加作为的PasswordEncoder属性,以验证Provider类。 Autowire它或提供setter和getter方法。

@AutoWired 
private BCryptPasswordEncoder passwordEncoder; 

取得属性而登录

<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> 

而且在认证类比赛两个密码

new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb) 
1

与3.1.X的权威性此映射不起作用你authendicate用户。 工作方式是:

<beans:bean id='bCryptPasswordEncoder' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder'></beans:bean> 

<authentication-manager> 
    <authentication-provider user-service-ref="userDetailsService"> 
      <password-encoder ref="bCryptPasswordEncoder"/> 
    </authentication-provider> 
</authentication-manager> 
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"/> 

在Java

public static String encodePasswordWithBCrypt(String plainPassword){ 
    return new BCryptPasswordEncoder().encode(plainPassword); 
} 

然后对其进行测试

System.out.println(encodePasswordWithBCrypt("fsdfd")); 
2

接受的答案是正确的。 我用spring 3.1BCrypt进行了测试编码算法。

创建用户时。

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword())); 
userDao.save(userEntity); 

当用户登录时,请记住,使用普通的密码(未散列)。就像:

Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword()); 
Authentication result = authenticationManager.authenticate(request); 
SecurityContextHolder.getContext().setAuthentication(result); 

这里是安全配置:

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

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
     <property name="userDetailsService" ref="userService" /> 
     <property name="hideUserNotFoundExceptions" value="false" /> 
     <property name="passwordEncoder" ref="encoder" /> 
    </bean> 

希望这将帮助别人!

2

与注释

@Configuration 
@EnableWebSecurity 
@PropertySource("classpath://configs.properties") 
public class SecurityContextConfig extends WebSecurityConfigurerAdapter { 


@Autowired 
@Qualifier("userDetailsService") 
private UserDetailsService userDetailsService; 

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder()); 
} 


@Bean(name = "passwordEncoder") 
public PasswordEncoder getPasswordEncoder(){ 
    return new BCryptPasswordEncoder();  
} 

}