SpringSecurityOAuth2授权失败(401)问题整理

更新时间:2023-05-21 19:53:35 阅读: 评论:0

SpringSecurityOAuth2授权失败(401)问题整理
项⽬中采⽤OAuth2四种模式中的两种,Password模式和Client模式, Password模式⽤于控制⽤户的登录,Client模式⽤于控制后端服务相互调⽤。
权限架构调整后在近期发现⼀些问题,由于⽹上资料不多,只能单步调试⽅式看源码(其实带着问题看源码是最好的⽅式)。现在将问题和解决⽅案整理如下:
⼀、免登录接⼝校验token问题
问题:APP端反馈,⼀些免登录接⼝会校验token
详细:经过测试发现,免登录接⼝如果传了access_token会对token合法性就⾏校验,如果不传接⼝不会校验,这导致了免登录接⼝的过期token会报错
排查:经过查看源码发现spring-curity-oauth2的过滤器 OAuth2AuthenticationProcessingFilter会对请求进⾏拦截,(具体源码就不截图了)
如果存在access_token 则会根据urInfoEndpointUrl去认证服务器上校验token信息,
跨考
如果不存在access_token 则会继续执⾏spring-curity的拦截器FilterSecurityInterceptor。 FilterSecurityInterceptor对路径是否需要授权,已经授权是否通过做校验~ 
解决:可以采⽤过滤器在执⾏到核⼼过滤器OAuth2AuthenticationProcessingFilter ,将不需要授权的请求头中的access_token过滤掉。或者APP免登录接⼝不传token
最终采⽤的是后者
⼆、Token失效返回的是状态401的错误
1、问题: APP端反馈,传递失效access_token,返回401状态,期望是200同时以错误码⽅式提⽰token失效。
排查:经过单步调试分析源码发现,token失效后,认证服务器会抛出异常,同时响应给资源服务器,资源服务发现认证服务器的错误后会抛出InvalideException。
抛出的异常会经过默认的DefaultWebResponExceptionTranslator 处理然后 Repon给Client端。
解决:通过上⾯的分析指导。最后的异常是在DefaultWebResponExceptionTranslator 处理的,所以只需要
⾃定义实现类Implements WebResponExceptionTranslator 接⼝处理异常装换逻辑,
使得⾃定义的类⽣效ballast
 (1)⾃定义异常转换类
1 @Slf4j
2public class Auth2ResponExceptionTranslator implements WebResponExceptionTranslator {amountof
3
4    @Override
5public ResponEntity<OAuth2Exception> translate(Exception e) {
6        ("Auth2异常", e);
7        Throwable throwable = e.getCau();
8if (throwable instanceof InvalidTokenException) {
青蛙公主 日剧9            log.info("token失效:{}", throwable);
10return new ResponEntity(new Message<>(ServerConstant.Msg(), ServerConstant.Code()), HttpStatus.OK);
11        }
12return new ResponEntity(new Message(), String.valueOf(HttpStatus.METHOD_NOT_ALLOWED.value())), HttpStatus.METHOD_NOT_ALLOWED);
fally
13    }
伟大辩手14 }
(2)资源服务器中使得⾃定义类⽣效
1 @Configuration
2 @EnableResourceServer
3public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
4割肉相啖
5
6  @Override
母亲节是国际节日吗7public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// 定义异常转换类⽣效
8    AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
9    ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).tExceptionTranslator(new Auth2ResponExceptionTranslator());
10    resources.authenticationEntryPoint(authenticationEntryPoint);
11  }
12
13
14  @Override
15public void configure(HttpSecurity http) throws Exception {
16    http
17        .csrf().disable()
18        .exceptionHandling()
// 定义的不存在access_token时候响应
19        .authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
20        .and()
21        .authorizeRequests().antMatchers("/**/**").permitAll()
22        .anyRequest().authenticated()
candy的意思
23        .and()
24        .httpBasic().disable();
25  }
2、问题:测试发现授权接⼝,当请求参数中不存在access_token时发现接⼝返回错误信息:
{"timestamp":1539337154336,"status":401,"error":"Unauthorized","message":"No message
erectavailable","path":"/app/businessCode/list"}
排查:经过前⾯的分析发现,上⾯提到Security的FilterSecurityInterceptor对OAuth2中返回的信息和本⾝配置校验后,抛出AccessDenyException。
解决:经过上⾯的⼏个问题的处理,发现思路还是⼀样的,需要定义响应结果,
即1、⾃定义响应处理逻辑SecurityAuthenticationEntryPoint 2、⾃定义处理逻辑SecurityAuthenticationEntryPoint⽣效(见上⾯的配置)
SecurityAuthenticationEntryPoint具体实现:
1 @Slf4j
2public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
3
4    @Override
5public void commence(HttpServletRequest request, HttpServletRespon respon, AuthenticationException authException) throws IOException, ServletException {
6        ("Spring Securtiy异常", authException);
7        respon.tCharacterEncoding("UTF-8");
8        respon.tContentType("application/json; chart=utf-8");
9        PrintWriter out = Writer();
10        out.JSONString(new Message<>(ServerConstant.Msg(), ServerConstant.Code())));
11    }
12 }

本文发布于:2023-05-21 19:53:35,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/117470.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:发现   校验   定义   服务器
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图