大家好,我是不才陈某~
这是《Spring Cloud 进阶》第24篇文章,往期文章如下:
- 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强?
- openFeign夺命连环9问,这谁受得了?
- 阿里面试这样问:Nacos、Apollo、Config配置中心如何选型?这10个维度告诉你!
- 阿里面试败北:5种微服务注册中心如何选型?这几个维度告诉你!
- 阿里限流神器Sentinel夺命连环 17 问?
- 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)
- Spring Cloud Gateway夺命连环10问?
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
- 分布式链路追踪之Spring Cloud Sleuth夺命连环9问?
- 链路追踪自从用了SkyWalking,睡的真香!
- 3本书了,7万+字,10篇文章,《Spring Cloud 进阶》基础版 PDF
- 妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 一次说明白!
- OAuth2.0实战!使用JWT令牌认证!
- OAuth2.0实战!玩转认证、资源服务异常自定义这些骚操作!
- 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
- 字节面试这样问:跨库多表存在大量数据依赖问题有哪些解决方案?
- 实战!退出登录时如何借助外力使JWT令牌失效?
- 实战!Spring Cloud Gateway集成 RBAC 权限模型实现动态权限控制!
- 实战!阿里神器 Seata 实现 TCC模式 解决分布式事务,真香!
- 实战!openFeign如何实现全链路JWT令牌信息不丢失?
- 微服务下蓝绿发布、滚动发布、灰度发布等方案,必须懂!
- 微服务如何聚合 API 文档?这波秀~
- Spring Cloud 2021.0.1 正式发布,卷不动了~
本篇文章介绍一下Spring Security如何扩展新的授权类型,也是实际开发中非常重要的知识点。
目录如下:
为什么需要自定义授权类型?
前面介绍OAuth2.0的基础知识点时介绍过支持的4种授权类型,分别如下:
- 授权码模式
- 简化模式
- 客户端模式
- 密码模式
关于上述4种授权类型不清楚的,可以看之前的文章:妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 一次说明白!
实际生产中上述四种授权类型根本不够用,比如常见的授权类型如下:
- 微信认证
- QQ认证
- 手机号+验证码认证
- 图形验证码认证
- 邮箱认证
因此我们必须懂得OAuth2.0如何自定义授权类型,这也是本篇文章的重点。
实现思路
Spring Security 定制授权类型其实很简单,主要是掌握其中的思路,下面是密码模式的授权流程,如下图:
根据上述流程图可以跟着源码进去看看,不难发现有几个如下重要点:
- 每种授权类型都对应一个实现类TokenGranter,其中定义着授权类型
- 所有
TokenGranter
实现类都通过CompositeTokenGranter
中的tokenGranters
集合存起来。 - 然后通过判断
grantType
参数来定位具体使用那个TokenGranter
实现类来处理授权。 - 每种授权方式都对应一个AuthenticationProvider
TokenGranter
类会 new 一个 AuthenticationToken实现类,如UsernamePasswordAuthenticationToken
传给ProviderManager
类。
因此想要自定义一个授权类型,必须构建自己的TokenGranter、AuthenticationProvider、AuthenticationToken。
代码实现
下面就以手机号+密码的登录方式定义一个类型:mobile_pwd,剩下的自己照葫芦画瓢。
1、自定义UserDetailService
这个和密码授权类型类似,要实现一个方法从数据库中根据手机号查询用户的详细信息。
定义一个SmsCodeUserDetailService接口如下:
主要就是一个 loadUserByMobile() 方法,实现类如下:
2、自定义AuthenticationToken
类似于密码模式的中UsernamePasswordAuthenticationToken,自定义一个MobilePasswordAuthenticationToken封装手机号和密码,如下:
3、自定义TokenGranter
每种授权类型都对应一种TokenGranter,其中会定义授权类型的名称,比如密码模式的ResourceOwnerPasswordTokenGranter,其中的GRANT_TYPE为password。
自定义一个MobilePwdGranter,照葫芦画瓢,模仿着改改,代码如下:
4、自定义AuthenticationProvider
这个类就是真正的处理类,经过TokenGranter后,会找到对应的AuthenticationProvider,然后取出参数从数据库(UserDetailService)中查询对应的信息进行匹配。
自定义MobilePasswordAuthenticationProvider,代码如下:
案例源码已上传GitHub,关注公众号:码猿技术专栏,回复关键:9529 获取!
5、将自定义的MobilePasswordAuthenticationProvider注入IOC容器
这里必须将自定义的MobilePasswordAuthenticationProvider注入到IOC容器,如果不注入,会报找不到能处理的AuthenticationProvider这个异常。
新建SmsCodeSecurityConfig,代码如下:
注意:由于使用的外部配置,因此必须在全局配置中指定
6、Security的全局配置指定SmsCodeSecurityConfig
由于是分开配置,因此必须在全局配置中指定才会生效,代码如下:
7、加到CompositeTokenGranter集合中
需要将自定义的授权类型加到集合CompositeTokenGranter中,此处需要修改认证中心的配置类(AuthorizationServerConfig)中的代码,如下:
8、oauth_client_details表中添加授权类型
oauth_client_details这个表是存储客户端的详细信息的,需要在对应的客户端资源那一行中的authorized_grant_types这个字段中添加自定义的授权类型,多个用逗号分隔。
测试
经过上述的步骤已经配置完成,下面来测试,启动服务,请求如下:
源码获取
授权类型主要是针对 认证中心(oauth2-cloud-auth-server) 的改动,改动的目录如下:
陈某直接在之前网关整合Spring Security的源码上更改了一版。
案例源码已上传GitHub,关注公众号:码猿技术专栏,回复关键:9529 获取!
最后说一句(别白嫖,求关注)
陈某每一篇文章都是精心输出,已经写了3个专栏,整理成PDF,获取方式如下:
- 《Spring Cloud 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Spring Cloud 进阶 获取!
- 《Spring Boot 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Spring Boot进阶 获取!
- 《Mybatis 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Mybatis 进阶 获取!
如果这篇文章对你有所帮助,或者有所启发的话,帮忙点赞、在看、转发、收藏,你的支持就是我坚持下去的最大动力!
关注公众号:【码猿技术专栏】,公众号内有超赞的粉丝福利,回复:加群,可以加入技术讨论群,和大家一起讨论技术,吹牛逼!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。