轉載請注明出處 http://www.cnblogs.com/majianming/p/7923604.html
最近在學習spring security,但是在設置客戶端密碼時,一直出現了一下錯誤提示,原來沒有問題的,認真上次到現在這之間的時間動了什么,我想到了我把 spring security 升級到了5.0.0,應該是這里的問題,那么總需要解決,回退也不是方法吧
仔細查找資料,發現了一下兩篇資料,其實是一樣的意思
https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
這個是原文
Password storage has undergone a major overhaul to provide more secure defaults and the ability to migrate how passwords are stored. The default
PasswordEncoder
is now DelegatingPasswordEncoder which is a non-passive change. This change ensures that passwords are now encoded using BCrypt by default, allows for validating passwords in old formats, and allows for upgrading the password storage in the future.
我簡單理解了一下,意思就是為了更加安全,所以就需要添加這個類型(id)
如果沒有加密的時候(也即是明文保存),需要改為這樣,假設明文密碼是password
password -> {noop}password // noop是no operate的意思,也就是說明保存的密碼沒有做加密操作
總的來說就是在spring security 4的密碼格式上添加了密碼類型的標記,並將這個標記使用花括號包裹放在密碼密文的前面,形成spring security 5 的密碼格式
加密類型支持(為了方便書寫,這里假設各類加密方式加密后的密碼密文是password)
加密方式 | 原來security 4的密碼格式 | 現在security 5的密碼格式 |
bcrypt | password | {bcrypt}password |
ldap | password | {ldap}password |
MD4 | password | {MD4}password |
MD5 | password | {MD5}password |
noop | password | {noop}password |
pbkdf2 | password | {pbkdf2}password |
scrypt | password | {scrypt}password |
SHA-1 | password | {SHA-1}password |
SHA-256 | password | {SHA-256}password |
sha256 | password | {sha256}password |
接下來介紹一下分析。如果我們不添加這個類型會怎么樣,我們查看 org.springframework.security.crypto.password.DelegatingPasswordEncoder 這個類,在里面一個內部類UnmappedIdPasswordEncoder的matches方法拋出了一個異常信息There is no PasswordEncoder mapped for the id \"" + id + "\"",這不就是我們拋出的異常嗎?
繼續看看代碼,在DelegatingPasswordEncoder初始化成員變量時候 ,有這樣的定義
private PasswordEncoder defaultPasswordEncoderForMatches = new UnmappedIdPasswordEncoder();
也就是說這里將UnmappedIdPasswordEncoder()設置為了默認,在matches函數中
String id = extractId(prefixEncodedPassword); PasswordEncoder delegate = this.idToPasswordEncoder.get(id);
if(delegate == null) {
return this.defaultPasswordEncoderForMatches
.matches(rawPassword, prefixEncodedPassword);
}
這里,調用了默認的matches函數,也就是UnmappedIdPasswordEncoder的matches,如果設置在數據庫密碼沒有帶{}這樣的標記,或者標記里的encode id 沒有在聲明的id 集合內(id集合是什么?也就是上面表格中所支持的加密格式,在運行時候DelegatingPasswordEncoder的構造函數打個斷點就知道了,其實就是idToPasswordEncoder這個變量的值,這個值定義PasswordEncoderFactories類中),那么它就拋出異常。
String prefixEncodedPassword) { String id = extractId(prefixEncodedPassword); throw new IllegalArgumentException("There is no PasswordEncoder mapped for the id \"" + id + "\"");
轉載請注明出處 http://www.cnblogs.com/majianming/p/7923604.html
使用版本:
spring security 5.0.0.RELEASE