| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发测试 -> OAuth2.0实战 认证、资源服务异常自定义这些骚操作 -> 正文阅读 |
|
[开发测试]OAuth2.0实战 认证、资源服务异常自定义这些骚操作 |
案例服务搭建此篇文章沿用上篇文章的认证、资源服务,如下: 1、认证服务oauth2-auth-server-jwt 2、资源服务oauth2-auth-resource-jwt “ 认证服务的异常先来看一下正确的获取令牌的请求,以密码模式为例,如下图: 密码模式需要传递5个参数,分别是用户名、密码、客户端id,客户端秘钥、授权类型。 那么问题来了:如果任意一个参数传错了,返回什么? 1、用户名、密码错误故意输错用户名或者密码,返回信息如下: 2、授权类型错误输入一个不存在的授权类型,返回信息如下: 3、客户端ID,秘钥错误输入错误的客户端id或者秘钥,返回信息如下: 感觉如何?是不是很酸爽?很显然这返回的信息不适合前后端交互,别着急,下面介绍解决方案 认证服务自定义异常信息上面列举了三种常见的异常,解决方案实际可以分为两种:
陈某这里针对这两种异常先上解决方案,后面再从源码解释为什么这么做? 1、用户名,密码错误异常、授权类型异常针对用户名、密码、授权类型错误的异常解决方式比较复杂,需要定制的比较多。 1、定制提示信息、响应码 这部分根据自己业务需要定制,陈某这里只是给出个例子,代码如下: 2、自定义WebResponseExceptionTranslator 需要自定义一个异常翻译器,默认的是DefaultWebResponseExceptionTranslator,此处必须重写,其中有一个需要实现的方法,如下:
这个方法就是根据传递过来的Exception判断不同的异常返回特定的信息,这里需要判断的异常的如下:
创建一个OAuthServerWebResponseExceptionTranslator实现WebResponseExceptionTranslator,代码如下: 3、认证服务配置文件中配置 需要将自定义的异常翻译器OAuthServerWebResponseExceptionTranslator在配置文件中配置,很简单,一行代码的事。 在AuthorizationServerConfig配置文件指定,代码如下: “ 4、测试 按照上述的配置完成后,测试下用户名、密码错误、授权类型错误是否能够正确返回定制的提示信息,如下: 用户名、密码错误 授权类型不支持 5、源码追踪 实践有了,总该理解一下为什么这么做吧?下面从源码的角度告诉你为什么要这么做? 我们知道获取令牌的接口为?/oauth/token,这个接口定义在TokenEndpoint#postAccessToken()(POST请求)方法中,如下图: 我们先不看其中的逻辑,平时我们写接口的异常怎么处理? 一般都是通过?@ExceptionHandler?特定的异常,然后统一的进行异常处理,是不是这样? 然后看一下上述的两种异常属于什么类型的,如下: UnsupportedGrantTypeException InvalidGrantException 是不是都继承了OAuth2Exception,那么尝试在TokenEndpoint这个类中找找有没有处理OAuth2Exception这个异常的处理器,果然找到了一个?handleException()?方法,如下: 可以看到,这里的异常翻译器已经使用了我们自定义的OAuthServerWebResponseExceptionTranslator。可以看下默认的异常翻译器是啥,代码如下: 看到没,就是这个DefaultWebResponseExceptionTranslator 问题又来了:为什么在配置文件中设置了OAuthServerWebResponseExceptionTranslator就会生效呢? 这个不得不看下?@EnableAuthorizationServer?这个注解了,源码如下: 注入了这个AuthorizationServerEndpointsConfiguration配置类,其中注入了AuthorizationEndpoint这个bean,如下: 将自定义的异常翻译器设置进入了AbstractEndpoint这个抽象类中,而TokenEndpoint正是继承了这个抽象类,复用了其中的异常翻译器,代码如下: 哦了,问题解决了,学东西一定要知其所以然............... 2、客户端ID、秘钥异常这部分比较复杂,想要理解还是需要些基础的,解决这个异常的方案很多,陈某只是介绍其中一种,下面详细介绍。 1、定制提示信息、响应码 这部分根据自己业务需要定制,陈某这里只是给出个例子,代码如下: 2、自定义AuthenticationEntryPoint 这个AuthenticationEntryPoint是不是很熟悉,前面的文章已经介绍过了,此处需要自定义来返回定制的提示信息。 创建OAuthServerAuthenticationEntryPoint,实现AuthenticationEntryPoint,重写其中的方法,代码如下: 3、改造ClientCredentialsTokenEndpointFilter ClientCredentialsTokenEndpointFilter这个过滤器的主要作用就是校验客户端的ID、秘钥,代码如下: 有几个重要的部分需要讲一下,如下:
4、OAuth配置文件中指定过滤器 只需要将自定义的过滤器添加到AuthorizationServerSecurityConfigurer中,代码如下: 第①部分是添加过滤器,其中authenticationEntryPoint使用的是第2步自定义的OAuthServerAuthenticationEntryPoint 第②部分一定要注意:一定要去掉这行代码,具体原因源码解释。 “ 5、测试 直接输入错误的秘钥,结果如下: 6、源码追踪 1、OAuthServerAuthenticationEntryPoint在何时调用? OAuthServerAuthenticationEntryPoint这个过滤器继承了?AbstractAuthenticationProcessingFilter?这个抽象类,一切的逻辑都在?doFilter()?中,陈某简化了其中的关键代码如下:
关键代码在?unsuccessfulAuthentication()?这个方法中,代码如下: 2、自定义的过滤器如何生效的? 这个就要看?AuthorizationServerSecurityConfigurer#configure()?这个方法了,其中有一段代码如下: 这段代码就是遍历添加的过滤器将其添加到过滤器链中,在BasicAuthenticationFilter这个过滤器之前。 添加到security的过滤器链中,这个过滤器自然会生效了。 3、为什么不能加.allowFormAuthenticationForClients()? 还是在?AuthorizationServerSecurityConfigurer#configure()?这个方法中,一旦设置了?allowFormAuthenticationForClients?为true,则会创建?ClientCredentialsTokenEndpointFilter,此时自定义的自然失效了。 资源服务器的异常从认证服务获取到令牌之后去请求资源服务的资源,这里涉及到的异常主要有两个,如下: 1、令牌失效比如令牌不正确、过期,此时返回的异常提示如下: 2、权限不足令牌的权限不足,比如?/admin?接口只允许?admin?角色访问,此时返回的异常信息如下: 资源服务自定义异常信息下面针对上述两种异常分别定制异常提示信息,这个比认证服务定制简单。 1、令牌失效这个比较简单,也是需要自定义AuthenticationEntryPoint。步骤如下: 1、自定义AuthenticationEntryPoint 这个和认证服务的客户端异常类似,这里不再详细说了,直接贴代码,如下: 2、OAuth配置文件中配置 这个比较简单,直接在配置文件中配置即可,代码如下: 3、测试 此时拿着失效的令牌访问资源服务,可以看到已经正常返回定制的提示信息了,如下: 源码和认证服务的类似,自己断点试试,还是很简单的。 “ 2、权限不足这个异常定制就更简单了,陈某在第一篇文章:实战!Spring Boot Security+JWT前后端分离架构登录认证!介绍过,下面简单的贴下代码。 1、自定义AccessDeniedHandler 代码如下: 2、OAuth配置文件中配置 和令牌失效的异常配置在同一个方法中,代码如下: 3、测试 访问?/admin?接口,此时的提示信息如下: |
|
开发测试 最新文章 |
pytest系列——allure之生成测试报告(Wind |
某大厂软件测试岗一面笔试题+二面问答题面试 |
iperf 学习笔记 |
关于Python中使用selenium八大定位方法 |
【软件测试】为什么提升不了?8年测试总结再 |
软件测试复习 |
PHP笔记-Smarty模板引擎的使用 |
C++Test使用入门 |
【Java】单元测试 |
Net core 3.x 获取客户端地址 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/17 22:27:02- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |