微服务常见认证、鉴权方案

笔者参考网上一些优秀开源项目和框架,谈谈常见的微服务认证、鉴权方案。内容有SecurityOauth2、单点登录cas、自定义拦截器开发、微服务间鉴权、令牌的存储方式、shiro由单体改动为微服务

微服务认证、鉴权的目标:

  • 一次登录后,各微服务都能访问
  • 可对各微服务进行角色、接口等粒度的鉴权

目录

一.SecurityOauth2

1.基本流程 

2.差异化

3.优缺点

4.优秀案例

二.自定义拦截器

 三.Cas单点登录

1.基本流程

2.优秀案例

四.微服务系统和集成到其他系统的cas

五.shiro

六.微服务间鉴权

七.关于令牌的存储方式


一.SecurityOauth2

可能是seurity框架提供了一个微服务鉴权的直接解决方式,导致网上资料大部分都是此类方案。

1.基本流程 

这个方案理解起来并不难。

  1. 首先,在登录时,利用oauth2协议的四种方式及自定义扩展方式进行登录,oauth-server服务签发一个令牌。
  2. 然后在网关进行令牌认证和权限校验,最后在业务服务拦截器中形成secuirty用户上下文。
  3. Oauth2有授权服务器、资源服务器的概念,授权服务器签发令牌,资源服务提供资源。但具体把网关和下游服务整体当做资源服务,还是每个下游服务是独立资源服务,不一定。

2.差异点

以下差异点是笔者根据一些开源项目的总结,并没有标准的实现方式,根据需求而定。

网关如何拦截?方式有:

  1. 可自定义过滤器,使用WebFlux过滤器,或者使用gateway过滤器
  2. 可把网关当做资源服务,用security鉴权管理拦截。如下链接
  3. https://www.cnblogs.com/haoxianrui/p/13719356.html#%E5%9B%9B-%E8%B5%84%E6%BA%90%E6%9C%8D%E5%8A%A1%E5%99%A8

 网关如何对令牌的认证?方式有

  1. 有网关自己解析令牌的,即网关有解析令牌的秘钥(无状态令牌)、或者知道令牌对应的session(有状态令牌)
  2. 有发送请求到ouath服务解析令牌的。

网关如何查询用户的权限数据?方式有

  1. 有网关直接用sql查询的,在网关直接查询数据库
  2. 有先发请求到其他服务查的,再保存到缓存

网关如何把用户信息传递到下游服务,方式有:

  1. 可以把用户和其权限数据,加密为一个jwt令牌,放到请求头中,用对称加密性能快点,当做一个内部令牌,然后让下游服务解析
  2. 可以光把用户id放到请求头,下游服务根据userid再去查,通常会加缓存

下游服务如何形成securiyt用户上下文?方式有

  1. 有自定义过滤器的
  2. 有把下游服务当做资源服务,用security拦截器的。如
  3. https://www.freesion.com/article/88371064512/

3.优缺点

优点:网上资料案例多,security有适配webflux的版本,能方便和springcloud gateway结合,同时因为oauth2的原因提供的登录方式很多,易扩展。

缺点:只在gateway鉴权,下游服务相互之间通信没有考虑。

4.优秀案例

新手必读 · 《灯灯》中后台快速开发平台开发手册 · 看云

项目简介 · 企业级微服务框架项目技术文档 · 看云

汉德平台是不错的开源企业案例:https://open.hand-china.com/

二.自定义拦截器

结构图跟上一个方式一样,区别在于不用框架,自定义oauth-server服务签发令牌,自定义网关拦截器认证、校验权限,自定义下游服务拦截器进行服务间内部访问校验、解析用户信息。

优点:理解简单,根据需求开发。

缺点:功能都要自定义开发,这既是缺点也是优点,自己开发能够完全控制功能,去除框架多余的功能。

 三.Cas单点登录

1.基本流程

以上图有三个域名,cas-server域名,系统1域名,系统2域名。

 每个应用都加一个cas-client依赖,检测到首次访问系统1就重定向到cas-server登录,登录后签发一个系统1令牌、一个cas-server的cookie。访问系统2时cas-client检测未登录系统2,就又重定向到cas-server,但cas-server发现携带了cas-server域名的cookie,证明曾登录过,就签发发一个系统2令牌,系统2就返回数据,这个过程系统2并没有再次让用户登录,从而完成单点登录。

我这段描述中cas的术语使用不准确,但大意是这样。

如何校验权限?cas server只负责了认证,没管权限校验

  • 通常在cas-client中自定义开发

优点:

  • 成熟方案,可以与shiro结合
  • 适合子系统有不同的域名
  • 适合对接其他系统

缺点:

  • 如果多个系统有统一的微服务网关,放弃了在网关统一鉴权,要每个服务都用cas-client,鉴权的顺序下沉到下游服务,让各服务稍显重

2.优秀案例

关于shiro和单点登录shiro-example/pom.xml at master · zhangkaitao/shiro-example · GitHub

github有个优秀的开源项目,作者用单点登录的思想,自定义开发了单点登录,值得学习:

https://github.com/shuzheng/zheng

https://www.iteye.com/blog/shuzheng5201314-2343910

四.微服务系统和集成到其他系统的cas

案例参考hand平台:

汉得焱牛开放平台

把微服务各服务看成一个整体系统,一个域名,网关发现未登录,就重定向到oauth服务,oauth再重定向到cas-server 进行cas的登录流程,直到获取令牌。用户再次访问网关校验令牌有效,就不再去cas-server了。

优点:适合一个微服务系统和其他系统共用单点登录。

五.shiro

我之前写过一篇文章,适合shiro单体系统的改造。

​​​​​​https://mp.csdn.net/mp_blog/creation/editor/88087516​​​​​​https://mp.csdn.net/mp_blog/creation/editor/88087516也可以采用shiro cas的方式。

优点:业务代码不用改动,尤其适合业务代码和shiro耦合很重的情况,如在代码上使用了shiro的注解去控制认证和鉴权,适合于旧系统改动。

缺点:这两种方式将鉴权逻辑下沉到了微服务,没能在网关鉴权,有些浪费资源。

六.微服务间鉴权

如果只在网关鉴权,则微服务内部之间就没能鉴权。比如微服务A是订单服务,微服务B是支付服务,本来用户只有访问订单服务的权限,但订单服务有个接口内部访问了支付服务,就会导致用户能够间接访问到支付服务。

如果只在微服务内部鉴权,又浪费了网关鉴权。

我的看法是,微服务发出的请求加一个请求头service-name标识发出请求的服务名,包括网关也加,微服务加拦截器 拦截发现请求者是网关就不鉴权,因为在网关鉴权过了,如果请求者不是网关就鉴权。

也可以把鉴权粒度加粗,比如支付服务只允许订单服务访问,其他服务就直接不能访问,能粗粒度的控制一些。

七.关于令牌的存储方式

无状态和有状态令牌只和令牌存储有关,和前面鉴权的方案不等价。

有状态令牌,指令牌对应的内容在服务端有存储,如服务端session存用户信息,校验令牌即校验是否有对应存储,注销令牌就是把服务端存储删除。这种方式实现方便,缺点是需要存储,如果涉及分布式,往往不能再放内存,要第三方存储。

无状态令牌,如JWT,是把用户信息都放在了令牌中,校验令牌只要能解密令牌即令牌有效,如果令牌有效校验要通过服务端存储才能校验,则违反了无状态。这种方式服务端不需要存储,节省资源,但注销令牌需要额外设计。

方案设计适合功能就好,不必追求框架,以上几种常见做法也可以结合起来做,不必拘泥于一种。

  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值