1.2.5.3 BCryptPasswordEncoder
早期使用md5对密码进行编码,每次算出的md5值都一样,这样非常不安全,Spring Security推荐使用
BCryptPasswordEncoder对密码加随机盐,每次的Hash值都不一样,安全性高。
1、BCryptPasswordEncoder测试程序如下
@Test
public void testPasswrodEncoder(){
String password = "111111";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
for(int i=0;i<10;i++) {
//每个计算出的Hash值都不一样
String hashPass = passwordEncoder.encode(password);
System.out.println(hashPass);
//虽然每次计算的密码Hash值不一样但是校验是通过的
boolean f = passwordEncoder.matches(password, hashPass);
System.out.println(f);
}
}
2、在AuthorizationServerConfig配置类中配置BCryptPasswordEncoder
//采用bcrypt对密码进行Hash
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
3、测试
请求http://localhost:40400/auth/userlogin,输入正常的账号和密码进行测试
1.2.5.4 解析申请令牌错误信息
当账号输入错误应该返回用户不存在的信息,当密码错误要返回用户名或密码错误信息,业务流程图如下:
修改申请令牌的程序解析返回的错误:
由于restTemplate收到400或401的错误会抛出异常,而spring security针对账号不存在及密码错误会返回400及
401,所以在代码中控制针对400或401的响应不要抛出异常。
......
Map map = null;
try {
((RestTemplate) restTemplate).setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// 设置 当响应400和401时照常响应数据,不要报错
if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401 ) {
super.handleError(response);
}
}
});
//http请求spring security的申请令牌接口
ResponseEntity<Map> mapResponseEntity = restTemplate.exchange(path, HttpMethod.POST, new
HttpEntity<MultiValueMap<String, String>>(formData, header), Map.class);
map = mapResponseEntity.getBody();
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("request oauth_token_password error: {}",e.getMessage());
e.printStackTrace();
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
if(map == null ||
map.get("access_token") == null ||
map.get("refresh_token") == null ||
map.get("jti") == null){//jti是jwt令牌的唯一标识作为用户身份令牌
//获取spring security返回的错误信息
String error_description = (String) map.get("error_description");
if(StringUtils.isNotEmpty(error_description)){
if(error_description.equals("坏的凭证")){
ExceptionCast.cast(AuthCode.AUTH_CREDENTIAL_ERROR);
}else if(error_description.indexOf("UserDetailsService returned null")>=0){
ExceptionCast.cast(AuthCode.AUTH_ACCOUNT_NOTEXISTS);
}
}
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
......
用户不存在:
密码错误:
解决方案
1.2.5.5 测试
使用postman请求http://localhost:40400/auth/userlogin
1、输入正确的账号和密码进行测试
从数据库找到测试账号,本课程所提供的用户信息初始密码统一为111111
2、输入错误的账号和密码进行测试