There is no PasswordEncoder mapped for the id “null”異常解決辦法
一. 問題描述
Spring security 5.0中新增了多種加密方式,也改變了默認(rèn)的密碼格式.
我們來看一下官方文檔:
The general format for a password is:
{id}encodedPassword
Such that id is an identifier used to look up which PasswordEncoder should be used and encodedPassword is the original encoded password for the selected PasswordEncoder. The id must be at the beginning of the password, start with { and end with }. If the id cannot be found, the id will be null. For example, the following might be a list of passwords encoded using different id. All of the original passwords are "password".
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=?
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
這段話的意思是說,現(xiàn)如今Spring
Security中密碼的存儲(chǔ)格式是“{id}…………”.前面的id是加密方式,id可以是bcrypt、sha256等,后面跟著的是加密后的密碼.也就是說,程序拿到傳過來的密碼的時(shí)候,會(huì)首先查找被“{”和“}”包括起來的id,來確定后面的密碼是被怎么樣加密的,如果找不到就認(rèn)為id是null.這也就是為什么我們的程序會(huì)報(bào)錯(cuò):There is no PasswordEncoder mapped for the id “null”.官方文檔舉的例子中是各種加密方式針對(duì)同一密碼加密后的存儲(chǔ)形式,原始密碼都是“password”.
二. 解決辦法
需要修改一下configure中的代碼,我們要將前端傳過來的密碼進(jìn)行某種方式加密,Spring Security 官方推薦的是使用bcrypt加密方式.
1. 內(nèi)存中存取密碼的修改方式
修改后是這樣的:
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
? //inMemoryAuthentication 從內(nèi)存中獲取
? auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("user1").password(new BCryptPasswordEncoder().encode("123")).roles("USER");
}
inMemoryAuthentication().passwordEncoder(new
BCryptPasswordEncoder())",這相當(dāng)于登陸時(shí)用BCrypt加密方式對(duì)用戶密碼進(jìn)行處理.以前的".password("123")"
變成了 ".password(new
BCryptPasswordEncoder().encode("123"))",這相當(dāng)于對(duì)內(nèi)存中的密碼進(jìn)行Bcrypt編碼加密.如果比對(duì)時(shí)一致,說明密碼正確,才允許登陸.
2. 在數(shù)據(jù)庫中存取密碼的修改方式
如果你用的是在數(shù)據(jù)庫中存儲(chǔ)用戶名和密碼,那么一般是要在用戶注冊時(shí)就使用BCrypt編碼將用戶密碼加密處理后存儲(chǔ)在數(shù)據(jù)庫中,并且修改configure()方法,加入".passwordEncoder(new
BCryptPasswordEncoder())",保證用戶登錄時(shí)使用bcrypt對(duì)密碼進(jìn)行處理再與數(shù)據(jù)庫中的密碼比對(duì).如下:
//注入userDetailsService的實(shí)現(xiàn)類
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
本套學(xué)習(xí)內(nèi)容順序由千鋒老師撰寫,版權(quán)歸千鋒教育長沙Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!