2011-12-15 100 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();  
} 

}