有沒有教程或沒有人有指示如何使用Spring-Security做以下事情?Spring Security自定義身份驗證和密碼編碼
任務:
我需要從我的數據庫認證的用戶名得到鹽,並用它來加密提供的密碼(從登錄頁面),將其與存儲的加密密碼(又名認證用戶)。
附加信息:
我使用自定義的數據庫結構。一個UserDetails
對象是通過自定義UserDetailsService
創建的,該自定義對象使用自定義DAOProvider從數據庫獲取信息。
我security.xml
文件至今:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
現在我想我需要
<password-encoder hash="sha" />
但還有什麼?我如何告訴spring security使用數據庫提供的鹽來編碼密碼?
編輯:
我發現This SO後是informatative但不是充分的:如果我在XML定義鹽源由密碼編碼器一起使用,例如:
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource"/>
</password-encoder>
我將不得不編寫一個自定義SaltSource來使用我的自定義鹽。但是這不是在UserDetails
對象內部找到的。所以......
選擇1:
我可以使用的UserDetails的自定義實現然後可能具有鹽的財產?
<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
來檢索鹽。
EDIT2:
剛剛得知,我的做法是..遺留.. :(所以我想我就用StandardPasswordEncoder
(我仍然要弄清楚如何準確使用)
順便說一句:我實現了第一個選項,用一個自定義的UserDetails類來擴展User類,然後添加一個salt屬性,然後將它作爲userPropertyToUse傳遞給SaltSource,就像它在SO後面提到的那樣在編輯1 ...
編輯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版本等列出的版本)。此外,文件談到了春季安全3.1,所以我認爲,我會隨之而去。
當創建一個用戶(對我來說只有一個管理員可以做到這一點),我只是用
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String result = encoder.encode(password);
和我做。
Spring Security將隨機創建一個salt並將其添加到密碼字符串中,然後將其存儲在數據庫中,所以不再需要salt column。
人們可以但是也可以提供一個全球性的鹽作爲構造函數的參數(new StandardPasswordEncoder("12345");
),但我不知道如何設置我的安全配置,以檢索一個bean是價值,而不是與<constructor-arg name="secret" value "12345" />
提供靜字符串。但是我不知道需要多少。
您的文章真的幫助我,我有非常類似的問題。 +1自我解決^^ – user1431729
我會建議BCryptPasswordEncoder而不是StandardPasswordEncoder。在安全性和與其他語言的互操作性方面,BCryptPasswordEncoder是更好的選擇 – Farm