SpringCloud系列之网关gateway-11.权限认证-分布式session替代方案

前面我们了解了Gateway组件的过滤器,这一节我们就探讨一下Gateway在分布式环境中的一个具体用例-用户鉴权。

传统单应用的用户鉴权

从我们开始学JavaEE的时候,就被洗脑式灌输了一种权限验证的标准做法,那就是将用户的登录状态保存到HttpSession中,比如在登录成功后保存一对key-value值到session,key是userId而value是用户后台的真实ID。接着创建一个ServletFilter过滤器,用来拦截需要登录才能访问的资源,假如这个请求对应的服务端session里找不到userId这个key,那么就代表用户尚未登录,这时候可以直接拒绝服务然后重定向到用户登录页面。
大家应该都对session机制比较熟悉,它和cookie是相互依赖的,cookie是存放在用户浏览器中的信息,而session则是存放在服务器端的。当浏览器发起服务请求的时候就会带上cookie,服务器端接到Request后根据cookie中的jsessionid拿到对应的session。
由于我们只启动一台服务器,所以在登录后保存的session始终都在这台服务器中,可以很方便的获取到session中的所有信息。用这野路子,我们一路搞定了各种课程作业和毕业设计。结果一到工作岗位发现行不通了,因为所有应用都是集群部署,在一台机器保存了的session无法同步到其他机器上。那我们有什么成熟的解决方案吗?
分布式环境下的解决方案

同步session

Session复制是最容易先想到的解决方案,我们可以把一台机器中的session复制到集群中的其他机器。比如Tomcat中也有内置的session同步方案,但是这并不是一个很优雅的解决方案,它会带来以下两个问题:
 Timing问题 同步需要花费一定的时间,我们无法保证session同步的及时性,也就是说,当用户发起的两个请求分别落在不同机器上的时候,前一个请求写入session的信息可能还没同步到所有机器,后一个请求就已经开始执行业务逻辑了,这不免引起脏读幻读。
 数据冗余 所有服务器都需要保存一份session全集,这就产生了大量的冗余数据
反向代理:绑定IP或一致性Hash

这个方案可以放在Nignx网关层做的,我们可以指定某些IP段的请求落在某个指定机器上,这样一来session始终只存在一台机器上。不过相比前一种session复制的方法来说,绑定IP的方式有更明显的缺陷:
 负载均衡 在绑定IP的情况下无法在网关层应用负载均衡策略,而且某个服务器出现故障的话会对指定IP段的来访用户产生较大影响。对网关层来说该方案的路由规则配置也极其麻烦。
 IP变更 很多网络运营商会时不时切换用户IP,这就会导致更换IP后的请求被路由到不同的服务节点处理,这样一来就读不到前面设置的session信息了
为了解决第二个问题,可以通过一致性Hash的路由方案来做路由,比如根据用户ID做Hash,不同的Hash值落在不同的机器上,保证足够均匀的分配,这样也就避免了IP切换的问题,但依然无法解决第一点里提到的负载均衡问题。

Redis解决方案

这个方案解决了前面提到的大部分问题,session不再保存在服务器上,取而代之的是保存在redis中,所有的服务器都向redis写入/读取缓存信息。
在Tomcat层面,我们可以直接引入tomcat-redis-session-manager组件,将容器层面的session组件替换为基于redis的组件,但是这种方案和容器绑定的比较紧密。另一个更优雅的方案是借助spring-session管理redis中的session,尽管这个方案脱离了具体容器,但依然是基于Session的用户鉴权方案,这类Session方案已经在微服务应用中被淘汰了。
分布式Session的替代方案

To think out of box guys~让我们把session抛到脑后,看看现在流行的两种认证方式:

OAuth 2.0

大家一定用过现在比较流行的第三方登录,比如我们通过微信扫码登录就可以登录某个应用的在线系统,但是这个应用并不知道我的微信用户名和密码。这便是我们要介绍的第一个鉴权方案-OAuth 2.0。
OAuth 2.0是一个开放授权标准协议,它允许用户让第三方应用访问该用户在某服务的特定私有资源,但是不提供账号密码信息给第三方应用。在上面的例子中,微信就相当于一个第三方应用,我们通过OAuth 2.0

image.png

拿微信登录第三方应用的例子来说:
 Auth Grant 在这一步Client发起Authorization Request到微信系统(比如通过微信内扫码授权),当身份验证成功后获取Auth Grant
 Get Token 客户端拿着从微信获取到的Auth Grant,发给第三方引用的鉴权服务,换取一个Token,这个Token就是访问第三方应用资源所需要的令牌
 访问资源 最后一步,客户端在请求资源的时候带上Token令牌,服务端验证令牌真实有效后即返回指定资源
我们可以借助Spring Cloud中内置的
spring-cloud-starter-oauth2
组件搭建OAuth 2.0的鉴权服务,OAuth 2.0的协议还涉及到很多复杂的规范,比如角色、客户端类型、授权模式等。这一小节我们暂且不深入探讨OAuth 2.0的实现方式,先来看另外一个更轻量级的授权方案:JWT鉴权。

JWT鉴权

JWT也是一种基于Token的鉴权机制,它的基本思想就是通过用户名+密码换取一个Access Token

鉴权流程

相比OAuth 2.0来说,它的鉴权过程更加简单,其基本流程是这样的:

  1. 用户名+密码访问鉴权服务验证通过:服务器返回一个Access Token给客户端,并将token保存在服务端某个地方用于后面的访问控制(可以保存在数据库或者Redis中)
    a. 验证失败:不生成Token
  2. 客户端使用令牌访问资源,服务器验证令牌有效性令牌错误或过期:拦截请求,让客户端重新申请令牌
    a. 令牌正确:允许放行

Access Token中的内容

JWT的Access Token由三个部分构成,分别是Header、Payload和Signature,我们分别看下这三个部分都包含了哪些信息:
 Header 头部声明了Token的类型(JWT类型)和采用的加密算法(HS256)
{'typ': 'JWT',
'alg': 'HS256'}
 Payload 这一段包含的信息相当丰富,你可以定义Token签发者、签发和过期时间、生效时间等一系列属性,还可以添加自定义属性。服务端收到Token的时候也同样可以对Payload中包含的信息做验证,比如说某个Token的签发者是“Feign-API”,假如某个接口只能允许“Gateway-API”签发的Token,那么在做鉴权服务时就可以加入Issuer的判断逻辑。
 Signature 它会使用Header和Payload以及一个密钥用来生成签证信息,这一步会使用Header里我们指定的加密算法进行加密
目前实现JWT的开源组件非常多,如果决定使用这个方案,只要添加任意一个开源JWT实现的依赖项到项目中的pom文件,然后在加解密时调用该组件来完成。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容