记一次spring mp redis项目整合security时遇到的离谱问题。 原先刚开始学习security权限框架,自以为学的还不错,就纯手打把seacurity整合进了自己项目,但是,自从配置security配置后,就开始了一路debug。。。
先是csrf没有关,然后又是UserDetails的自定义实现类封装不进去。 然后又是Encoded password does not look like BCrypt。 然后又是一直403 forbidden。。
1.security配置
然后我又把security和redis单拉出来重新写了个demo,来回排查终于搞定了。 下面是这个小demo的config代码
代码语言:javascript复制/**
* Created by Intellij IDEA
* Author: yi cheng
* Date: 2022/10/7
* Time: 15:47
**/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// @Resource
// private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
//关闭csrf
.csrf().disable()
//不通过Session获取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// 对于登录接口 允许匿名访问 anonymous
.antMatchers("/user/login").anonymous()
.anyRequest().authenticated();
//把token校验过滤器添加到过滤器链中
// http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* AuthenticationManager注册进容器
*
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
这里controller只定义了一个用户登录接口,所以放行login就行了。然后就是关闭csrf不用多说。
2.UserDetailsService的loadUserByUsername()返回值封装
封装UserDetails的自定义实现类LoginUser实现UserDetails,就是用户认证实体类 里面方法返回true或get方法返回username和password就行。
3.Encoded password does not look like BCrypt
这个错误具体原因是数据库加密后的密码加密方式与传入的匹配不了。
可以使用spring容器中注入的密码加密bean重新生成加密密码存入数据库
。
上面config里已经把BCryptPasswordEncoder注入到了spring容器,所以在test里调用一下即可。我这里是粗心又new 了一个BCryptPasswordEncoder进行的密码加密当测试用的,没想到挂在了这一步。
然后执行UserDetailsService中的方法会认证不通过,导致无法封装LoginUser返回对象,这样你的login方法的authenticationManager也就拿不到LoginUser这个对象,而只是把用户名封装了进去,连user对象都不是,所以后续一系列什么判断,new Authentication,存到redis类的都不会执行下去,控制台也不报错,中给个下面图片Encoded password does not look like BCrypt提示,肉眼很难发现,所以加密一定用bean中的bcrypt。
代码语言:javascript复制这个错不好发现,我的sql打印很多,要不是debug’实在没头绪我很难发现这有个错。
@Resource
private PasswordEncoder passwordEncoder;//容器中的 BCrypt
@Test
void pwdTest() {
// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();不要自己new
String pwd = passwordEncoder.encode("123456");
System.out.println(pwd1);
}
此方法就能解决上图报错 password does not look like BCrypt 或者postman一直403 forbidden
demo的github地址github