当前位置: 首页 > 后端技术 > Java

实战!SpringCloudGateway集成RBAC权限模型,实现动态权限控制!

时间:2023-04-01 19:12:58 Java

大家好,我是陈步才~这里是《Spring Cloud 进阶》的第18篇。openFeign的致命连环9题,谁受得了?阿里面试问:Nacos、Apollo、Config配置中心如何选择?这10个维度告诉你!阿里面试失败:5类微服务注册中心如何选择?这些维度告诉你!阿里的限流神器Sentinel杀连载17题?和7个分布式事务方案相比,我还是更喜欢阿里开源的Seata。真香!(原理+实战)SpringCloudGateway致命系列10题?SpringCloudGateway整合阿里哨兵网关限流实践!分布式链接跟踪SpringCloudSleuthDeadlyChain9个问题?由于我使用SkyWalking进行链接跟踪,所以我睡得很香!3本书,7万+字,10篇文章,《Spring Cloud 进阶》基础版PDF妹子永远不懂OAuth2.0,今天集成SpringCloudSecurity来讲解一次!OAuth2.0在行动!使用JWT令牌进行身份验证!OAuth2.0在行动!玩转认证,资源服务异常,自定义这些风骚操作!实际干货!SpringCloudGateway集成OAuth2.0实现分布式统一认证授权!字节面试问:对于大量跨库跨表的数据依赖问题有哪些解决方案?实战!退出时如何通过外力使JWTtoken失效?本文介绍网关层如何集成RBAC权限模型进行认证鉴权。文章内容如下:什么是RBAC权限模型?RBAC(Role-BasedAccessControl)是基于角色的访问控制,是目前使用最广泛的权限模型。相信大家对这种权限模型有了更深入的了解。此模型具有三个用户、角色和权限。在传统的权限模型中,用户直接关联到一个角色层,将用户与权限解耦,使得权限体系的职责分工更加清晰,灵活性更高。以上五张表的SQL就不详细贴出来了,放在案例源码的doc目录下,如下图:设计思路RBAC权限模型是基于角色的,所以权限在SpringSecurity是角色,具体的认证授权过程如下:通过UserDetailService查询用户登录应用token,加载密码、权限(角色)等用户信息。封装到UserDetails中,token申请成功,需要携带token访问资源网关层,比对访问的URL。权限(在Redis中)是否与当前令牌的权限重叠。如果有交集,说明你有访问该URL的权限。如果你有权限,你可以访问它,否则你可以拒绝它。以上只是一个大概的流程,还有一些细节需要讨论,如下:1、如何维护URL对应的权限?这是比较容易实现的。涉及到RBAC权限模式中的三张表,分别是权限表、角色表、权限角色对应表。具体实现过程如下:在项目启动时,将权限(URL)与角色的对应关系加载到Redis中。管理界面上的URL关系相关的变化,必须实时变化到Redis。比如权限里面有这么一条数据,如下:URL/order/info是一个权限,管理员可以给它分配一个指定的角色。2、如何实现Restful风格的权限控制?restful接口url都是一样的,唯一不同的是请求方式,所以为了实现权限的精细控制,需要保留请求方式,比如POST、GET、PUT、DELETE....都可以在权限表中的url字段放一个方法标识,比如POST,此时完整的URL为:POST:/order/info当然,*:/order/info中的星号表示满足所有请求方法。3、这样可以实现动态权限控制吗?控制权限的方式有很多种,比如Security自己的注解和方法拦截。其实扩展SpringSecurity也可以实现动态权限控制。这个会在后面的文章中单独介绍!Chen的文章是将权限和角色的对应关系存储在Redis中,所以如果要实现动态的权限控制,只需要在Redis中维护这个关系即可。Redis中的数据如下:案例实现本文依然是基于以下三个模块进行修改,不清楚的可以查看陈老师之前的文章。namefunctionoauth2-cloud-auth-serverOAuth2.0认证授权服务器oauth2-cloud-gateway网关服务oauth2-cloud-auth-commonpublic模块涉及的更改目录如下:1.加载URL<->角色对应从数据库项目一开始,Redis直接读取数据库中的权限,加载到Redis中。当然,方法有很多,大家可以根据情况选择。代码如下:这里的代码在oauth2-cloud-auth-server模块下。案例源码已上传到GitHub,关注公众号:码猿技术专栏,回复关键词:9529搞定!2、实现UserDetailsS??ervice加载权限UserDetailsS??ervice相信大家都不陌生。它的主要功能是根据用户名从数据库中加载用户详细信息。代码如下:①处的代码是通过JPA从数据库中查询用户信息并组装角色,必须以ROLE_开头。②处的代码是将获取到的角色封装到权限中传递下去。这里的代码在oauth2-cloud-auth-server模块下。案例源码已上传到GitHub,关注公众号:码猿技术专栏,回复关键词:9529搞定!3.认证管理器中的认证权限其实是上篇干的!SpringCloudGateway集成OAuth2.0实现分布式统一认证授权!认证管理器的作用前面已经详细介绍了,这里就不赘述了。代码如下:①处的代码是将请求URL组装成restful风格,如POST:/order/info②处的代码是从Redis中取出URL和角色对应关系进行遍历,通过AntPathMatcher进行比较,并获取当前请求所需角色的URL。③处的代码是比较当前URL需要的角色和当前用户的角色。分为两步:如果你是超级管理员,可以直接释放。您不需要比较权限。如果您不是超级管理员,则需要比较角色。有交集的时候才可以释放这个。代码在oauth2-cloud-gateway模块中。案例源码已上传到GitHub,关注公众号:码猿技术专栏,回复关键词:9529搞定!4.综上所述,关键代码就是以上三个地方。另外DAO层的一些相关代码就不再贴出来了。下载源码看看吧!案例源码已上传到GitHub,关注公众号:码猿技术专栏,回复关键词:9529搞定!额外改动本文顺便把客户端信息也放在了数据库中,而之前的文章都是放在内存中的。在数据库中新建一张表,SQL如下:CREATETABLE`oauth_client_details`(`client_id`varchar(48)NOTNULLCOMMENT'clientid',`resource_ids`varchar(256)DEFAULTNULLCOMMENT'resourceid,multipleusecomma-separated',`client_secret`varchar(256)DEFAULTNULLCOMMENT'client'ssecretkey',`scope`varchar(256)DEFAULTNULLCOMMENT'clientpermissions,multiplecomma-separated',`authorized_grant_types`varchar(256)DEFAULTNULLCOMMENT'授权类型,五种,逗号分隔',`web_server_redirect_uri`varchar(256)DEFAULTNULLCOMMENT'授权码方式的跳转uri',`authorities`varchar(256)DEFAULTNULLCOMMENT'权限,多个逗号分隔',`access_token_validity`int(11)DEFAULTNULLCOMMENT'access_token过期时间,毫秒,覆盖硬编码',`refresh_token_validity`int(11)DEFAULTNULLCOMMENT'refresh_token过期时间,毫秒,覆盖硬编码',`additional_information`varchar(4096)DEFAULTNULLCOMMENT'扩展字段,JSON',`autoapprove`varchar(256)DEFAULTNULLCOMMENT'默认false,是否自动授权',PRIMARYKEY(`client_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8;认证服务中的OAuth2.0配置文件从数据库加载客户端信息。实现类为JdbcClientDetailsS??ervice,关键代码为代码如下:@Overridepublicvoidconfigure(ClientDetailsS??erviceConfigurerclients)throwsException{//使用JdbcClientDetailsS??ervice从数据库加载客户端信息clients.withClientDetails(newJdbcClientDetailsS??ervice(dataSource));}小结本文介绍了网关集成RBAC权限模型进行认证鉴权,核心思想是将权限信息加载到Redis缓存中,在网关级别的authenticationmanager中进行权限验证,其中还集成了宁静的风格