2012-02-15 49 views
5

有簡單的Spring Web應用安全與密碼編碼:認證Spring Security的蒙山編碼的密碼

<security:authentication-manager alias="authenticationManager"> 
<security:authentication-provider user-service-ref="personService"> 
    <security:password-encoder hash="md5" ref="passwordEncoder"> 
     <!-- <security:salt-source user-property="username"/> --> 
    </security:password-encoder> 
</security:authentication-provider> 
</security:authentication-manager> 

編碼也很簡單:

person.setPassword(encoder.encodePassword(person.getPassword(), null)); 

所以在數據庫中的所有密碼都將進行編碼。 現在我想要在應用程序中使用某個用戶名對某個用戶進行身份驗證。 之前(當passswords是明文),它是這樣的:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
       username, password); 
Authentication authentication = authenticationManager.authenticate(token); 
SecurityContextHolder.getContext().setAuthentication(authentication); 

但現在我得到的編碼從數據庫的密碼和不能做身份驗證之前。

問題所在。該Spring不知道密碼來自已經編碼的UsernamePasswordAuthenticationToken。而且他第二次編碼。 誰可以幫忙?

編輯

所以,我在這裏看到的兩個解決方案:

  1. 實現自定義DaoAuthenticationProvider的時候在那裏添加檢查,如果這兩個密碼散列已經
  2. 實現自定義的身份驗證和手動把它在安全上下文。

其他?哪個最好?

+0

包括一些SpringSecurity在[詳細這裏(http://techastute.blogspot.com /2013/01/spring-security-in-detail.html),可能對某個人有用。 – raksja 2013-01-21 17:51:21

回答

7

您實際上並沒有說出錯的地方,但驗證碼應該與非哈希版本完全相同。

如果數據庫中存在哈希密碼,並且注入驗證提供程序的編碼器已被注入,則用戶提供的密碼將在與數據庫版本比較之前由編碼器進行散列處理。

請確認:

  1. 您在數據庫中創建的UsernamePasswordAuthenticationToken
  2. 值時所使用的非散列密碼值真的是一樣的由編碼器產生的哈希值。自己加載並在測試中檢查。例如,數據庫可能以大寫形式存儲它。

此外,你應該選擇比普通MD5更好的東西。例如,您可能想看看bcrypt,它在Spring Security 3.1中受支持,並自動使用隨機salt值。

更新

你創造它接受哈希密碼供應商的建議是不是一個好一個。這將允許任何竊取密碼散列的人直接進行驗證(因此首先破壞散列的目的)。

只需驗證您的郵件的URL鏈接,加載該用戶的信息,併爲他們創造一個Authentication對象:

UserDetails user = ... // load user here 
Authentication a = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(a); 
+0

問題出在1.當創建UsernamePasswordAuthenticationToken時,我只有散列版本的密碼,因爲我從數據庫加載UserDetails對象(在我的情況下 - 通過確認鍵) – vacuum 2012-02-15 21:15:26

+0

使用存儲的密碼不會驗證用戶(我認爲是你正在嘗試做什麼)。如果沒有,你需要澄清你想要達到的目標。使用您事先知道的密碼來調用身份驗證管理器沒有多大意義。 – 2012-02-15 21:23:45

+0

我想驗證用戶,他點擊了註冊電子郵件中的鏈接。所以UserDetails對象來自數據庫,通過確認鍵來自電子郵件中的確認鏈接。 – vacuum 2012-02-15 21:37:32