springsecurity权限控制(Spring Security请求oauth/token接口报401 Unauthorized)
背景
项目spring-security+oauth2
版本是5.7.6
项目以client的形式请求TokenEndPoint中的/oauth/token ,使用Basic认证调用接口 ,返回token问题描述
先前是可以登录访问 ,更新代码之后 ,现在登录访问报401 Unauthorized
问题的难点是 ,这个错误信息是项目中请求以http方式请求TokenEndPoint中的/oauth/token返回的 ,请求并没有到达路径对应接口就返回了 ,我并没有了解过spring security中过滤器具体有哪些 ,所以不太好打断点 ,这导致我浪费很多的时间 。提示:在不了解的情况下,我使用的是笨方法 ,根据报错信息(Unauthorized) , 全局搜索,然后找到线索 。
在lib包中的代码 ,要搜索需要有源码原因
不废话 ,原因是走了下边过滤器的这段代码(注意,这是我的项目 ,走的该Filter ,自己的项目还需要结合实际情况来)。
BasicAuthenticationFilter.java
提示:以下代码已经处理过 ,只保留与本文有关逻辑内容
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { try { // 获取用户名 UsernamePasswordAuthenticationToken authRequest = this.authenticationConverter.convert(request); String username = authRequest.getName(); // 是否需要校验 if (authenticationIsRequired(username)) { // 校验 ,失败抛出异常 Authentication authResult = this.authenticationManager.authenticate(authRequest); // 通过 ,返回(空函数) onSuccessfulAuthentication(request, response, authResult); } } catch (AuthenticationException ex) { // 失败 ,返回(空函数) onUnsuccessfulAuthentication(request, response, ex); if (this.ignoreFailure) { // 是否忽略认证失败 chain.doFilter(request, response); } else { // 填充401状态和错误信息 this.authenticationEntryPoint.commence(request, response, ex); } return; } chain.doFilter(request, response); }Authentication authResult = this.authenticationManager.authenticate(authRequest);中会校验报错 ,然后被catch中的逻辑填充401 和报错信息 。
到这里 ,如果你也遇到类似问题 ,就通过这个类打个断点试试把 。具体原因
通过跟Authentication authResult = this.authenticationManager.authenticate(authRequest);中的校验代码,发现其通过循环找到对应的Provider去执行校验 ,如下图
其中provider是DaoAuthenticationProvider ,它继承自抽象类AbstractUserDetailsAuthenticationProvider,如下图
AbstractUserDetailsAuthenticationProvider实现了authenticate方法 ,其中逻辑主要取了用户凭证信息用以比对(这里就不展示了) 。
校验部分预留了模板方法 ,具体校验逻辑则下沉到子类DaoAuthenticationProvider中,类似模板方法模式 。其子类校验逻辑实现如下 ,通过passwordEncoder密码编码器比对参数中的凭证 ,与抽象类中获取的凭证信息是否一样 。
我出现报错的原因就是这个passwordEncoder的实例类发生了变动 ,因为pom中依赖版本升级 ,导致这个密码编码器在高版本中发生了改变 ,由原来的明文编码器变为了hash编码器 。
未升级前使用明文
升级后使用了hash加密
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!