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}
如果哪里有解释错误的,请不要喷,我只是一个卑微的码农