
只要 3 个注解,优雅的实现微服务鉴权!
大家好,我是不才陈某~
前面的文章中介绍了网关集成Spring Security实现网关层面的统一的认证鉴权。
有不清楚的可以看之前的文章:实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
最近订阅了《Spring Cloud Alibaba 实战》视频专栏的读者经常问陈某两个问题,如下:
- 鉴权放在各个微服务中如何做?
- feign的调用如何做到的鉴权?
今天针对以上两个问题深入聊聊如何通过三个注解解决。
实现思路
前面的几篇文章陈某都是将鉴权和认证统一的放在了网关层面,架构如下:
微服务中的鉴权还有另外一种思路:将鉴权交给下游的各个微服务,网关层面只做路由转发。
这种思路其实实现起来也是很简单,下面针对网关层面鉴权的代码改造一下即可完成:实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
1. 干掉鉴权管理器
在网关统一鉴权实际是依赖的鉴权管理器ReactiveAuthorizationManager,所有的请求都需要经过鉴权管理器的去对登录用户的权限进行鉴权。
这个鉴权管理器在网关鉴权的文章中也有介绍,在陈某的《Spring Cloud Alibaba 实战》中配置拦截也很简单,如下:
除了配置的白名单,其他的请求一律都要被网关的鉴权管理器拦截鉴权,只有鉴权通过才能放行路由转发给下游服务。
看到这里思路是不是很清楚了,想要将鉴权交给下游服务,只需要在网关层面直接放行,不走鉴权管理器,代码如下:
2. 定义三个注解
经过第①步,鉴权已经下放给下游服务了,那么下游服务如何进行拦截鉴权呢?
其实Spring Security 提供了3个注解用于控制权限,如下:
-
@Secured
-
@PreAuthorize
-
@PostAuthorize
关于这三个注解就不再详细介绍了,有兴趣的可以去查阅官方文档。
陈某这里并不打算使用的内置的三个注解实现,而是自定义了三个注解,如下:
1.@RequiresLogin
见名知意,只有用户登录才能放行,代码如下:
2.@RequiresPermissions
见名知意,只有拥有指定权限才能放行,代码如下:
3.@RequiresRoles
见名知意,只有拥有指定角色才能放行,代码如下:
以上三个注解的含义想必都很好理解,这里就不再解释了....
3. 注解切面定义
注解有了,那么如何去拦截呢?这里陈某定义了一个切面进行拦截,关键代码如下:
其实这中间的逻辑非常简单,就是解析的Token中的权限、角色然后和注解中的指定的进行比对。
“
@RequiresPermissions
这个注解的逻辑陈某并未实现,自己根据业务模仿着完成,算是一道思考题了....”
4. 注解使用
比如《Spring Cloud Alibaba 实战》项目中有一个添加文章的接口,只有超管和管理员的角色才能添加,那么可以使用@RequiresRoles
注解进行标注,如下:
效果这里就不演示了,实际的效果:非超管和管理员角色用户登录访问,将会直接被拦截,返回无权限。
注意:这里仅仅解决了下游服务鉴权的问题,那么feign调用是否也适用?
当然适用,这里使用的是切面方式,feign内部其实使用的是http方式调用,对于接口来说一样适用。
比如《Spring Cloud Alibaba 实战》项目中获取文章列表的接口,其中会通过feign的方式调用评论服务中的接口获取文章评论总数,这里一旦加上了@RequiresRoles
,那么调用将会失败,代码如下:
总结
本文主要介绍了微服务中如何将鉴权下放到微服务中,也是为了解决读者的疑惑,实际生产中除非业务需要,陈某还是建议将鉴权统一放到网关中。
文章转载自公众号: 码猿技术专栏
