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

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
鉴权流程
led间隔柱相⽐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⽂件,然后在加解密时调⽤该组件来完成。

本文发布于:2024-09-22 15:38:35,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/106451.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:验证   信息   请求   登录   服务   组件
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议