在SpringCloud架构中,实现受权功能有两种实现方式:html
-
在网关层进行受权java
-
由后端微服务本身受权spring
两种方式在此系列文章中都有实现方案,那么问题来了:哪一种才是最优方案,哪一种方案更合理呢?后端
很抱歉,看完这篇文章你也不必定能获得你想要的答案,由于结论是并无最优方案,两种方案各有千秋,只有根据自身业务选择对应的方案。本文咱们将两种方案作一个简单对比,以便大伙在作方案决策有个选择参考。服务器
解决方案对比
首先咱们看看两种方案实现的原理:若是对具体实现方式有疑问的同窗能够参考这篇文章:
SpringCloud Alibaba微服务实战十九 - 集成RBAC受权微信
网关受权
基于网关受权咱们又叫基于路径匹配器受权,请求在通过网关的时候校验当前请求的路径是否在用户拥有的资源路径中。restful
在基于路径匹配器受权时须要考虑restful风格的访问路径,如 /account-service/blog/user/{id}
或 /account-service/blog/**
等,因此在网关进行受权主要是基于通配符匹配。架构
微服务受权
微服务受权咱们又叫基于方法拦截,在资源上打上对应的方法标识而后分配给用户。在请求方法上经过对应的注解判断当前用户是否有访问此方法的权限。如SpringSecurity中的 @PreAuthorize("hasAuthority('')")
注解,Shiro中的 @RequiresPermissions('')
注解。不论是SpringSecurity仍是Shiro他们实现原理都是基于关键字彻底匹配。微服务
优缺点对比
网关受权
优势性能
使用网关受权的优势很明显,后端全部微服务只须要是普通的服务便可,再也不须要依赖权限那一套。
缺点
-
通配符匹配在网关作性能比较差,通配符要拆分,先匹配前缀,前缀匹配了再匹配通配符。这里你们能够看看
org.springframework.util.AntPathMatcher#doMatch()
的实现逻辑。 -
对于Restful风格的URL路径,不能精细化控制权限
例如一个微服务有以下API
GET /v1/pb/user
POST /v1/pb/user
PUT /v1/pb/user
这样在网关经过request.getURI().getPath()
方法获取到用户请求路径的时候都是同一个地址,给一个用户授予/v1/pb/user
权限后他就拥有了GET
、PUT
、POST
三种不一样权限,很显然这样不能知足精细权限控制。至于如何解决这个问题,原来专门写过一篇文章讨论,感兴趣的同窗能够看看:SpringCloud Alibaba微服务实战二十五 - Restful接口拦截
微服务受权
优势:
上面提到网关受权的缺点其实是微服务受权的优势,基于方法拦截是彻底匹配,cpu消耗不多,并且也不存在RestFul的问题。
缺点:
实现较为复杂,在 SpringSecurity Oauth2
体系中须要所有引入资源服务器相关配置,因此通常会创建一个单独的资源服务器模块,这也是系列文章下篇内容须要解决的问题。
结论
这里咱们尝试对两种实现方案作一个总结,若是系统功能、业务模块不是不少能够采用网关受权模式,这样实现最简单也最方便,虽然存在Restful风格不能精细化权限控制问题,可是咱们加一个Method字段就能够解决。
若是你的系统规模比较大,有不少资源须要受权那就建议采用微服务受权模式,那为了不每一个微服务都须要处理权限校验的逻辑,咱们还须要抽取一个公共的权限认证模块供后端服务引用。
以上,但愿对你有所帮助!
本文分享自微信公众号 - JAVA日知录(javadaily)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。