There is no PasswordEncoder mapped for the id "null" 解決途徑


WebSecurityConfig基於Spring Security OAuth2和 JWT 構建保護微服務系統 的搭建過程可參考 https://www.jianshu.com/p/24764aba1012?utm_source=oschina-app

 

如果按照上面鏈接搭建遇到如題的問題

有如下兩種解決途徑

1、在類 WebSecurityConfig 中添加如下代碼

 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

 

修改類OAuth2Config中的代碼

    // 配置客戶端基本信息
 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("user-service")// 創建一個客戶端 名字是user-service
                .secret("$2a$10$AfWzWK7lF.TOFcZuifNjjeuA.OkFRlC6jYR.w33MtuH1d9.lKOMTy") .scopes("service") .authorizedGrantTypes("refresh_token", "password") .accessTokenValiditySeconds(3600); }

$2a$10$AfWzWK7lF.TOFcZuifNjjeuA.OkFRlC6jYR.w33MtuH1d9.lKOMTy 是123456的Base64編碼

 

2 、修改類OAuth2Config中的代碼,不修改WebSecurityConfig的代碼

    // 配置客戶端基本信息
 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("user-service")// 創建一個客戶端 名字是user-service
                .secret("{bcrypt}$2a$10$AfWzWK7lF.TOFcZuifNjjeuA.OkFRlC6jYR.w33MtuH1d9.lKOMTy") .scopes("service") .authorizedGrantTypes("refresh_token", "password") .accessTokenValiditySeconds(3600); }

 

{bcrypt}$2a$10$AfWzWK7lF.TOFcZuifNjjeuA.OkFRlC6jYR.w33MtuH1d9.lKOMTy-----bcrypt 是因為是用該方式進行編碼(還有其他很多種方式)

源碼分析:

1、因為類中注入了passwordEncoder這個Bean

在 類WebSecurityConfig的父類 WebSecurityConfigurerAdapter方法中

        public boolean matches(CharSequence rawPassword, String encodedPassword) { return this.getPasswordEncoder().matches(rawPassword, encodedPassword); }

 

會進入 BCryptPasswordEncoder的matches方法來判斷之前的Base64編碼是否正確 

    public boolean matches(CharSequence rawPassword, String encodedPassword) { if (encodedPassword != null && encodedPassword.length() != 0) { if (!this.BCRYPT_PATTERN.matcher(encodedPassword).matches()) { this.logger.warn("Encoded password does not look like BCrypt"); return false; } else { return BCrypt.checkpw(rawPassword.toString(), encodedPassword); } } else { this.logger.warn("Empty encoded password"); return false; } }

 

2、因為沒有初始化BCryptPasswordEncoder類,所以會進入DelegatingPasswordEncoder的matches方法 

    public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) { if (rawPassword == null && prefixEncodedPassword == null) { return true; } else { String id = this.extractId(prefixEncodedPassword); PasswordEncoder delegate = (PasswordEncoder)this.idToPasswordEncoder.get(id); if (delegate == null) { return this.defaultPasswordEncoderForMatches.matches(rawPassword, prefixEncodedPassword); } else { String encodedPassword = this.extractEncodedPassword(prefixEncodedPassword); return delegate.matches(rawPassword, encodedPassword); } } }

 this.extractId()方法會以’{‘,’}‘截取字符串來判斷要用什么encoder

所以要在Base64編碼前加入 {bcrypt}

 

如果哪里有解釋錯誤的,請不要噴,我只是一個卑微的碼農

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM