微服务认证架构如何演进来的?

【答疑解惑作者 / Edison Zhou

这是恰童鞋骚年的第267篇原创内容


之前有同事问为何要用基于JWT令牌的认证架构,然后近期又有童鞋在后台留言问微服务安全认证架构的实践,因此我决定花两篇推文来解答一下。为了答好这个话题,我们先来看看微服务的安全认证架构是如何演进而来的,从而更好地理解。

1单块阶段(上)

首先,我们有必要再次了解下认证和授权这两个基本概念:

认证,Authentication,识别你是谁。即在网站上用来识别某个用户是否是注册过的合法用户。

授权,Authorization,识别你能做什么。即在网站上用来识别某个用户是否有某方面的权限。

然后,这里还是引用我在波波老师的《Spring Boot与K8s云原生应用开发》课程中学到的一个案例,来学习网站安全架构的演进。

假设我们把时间倒退回2006年,我们有一个叫做MyShop的网站,它的安全架构大概是下面这个样子,我们暂且称之为v1版本:

MyShop v1版本的认证操作

可以看到,这个v1版本的传统安全认证架构,使用到了我们十分熟悉的Session + Cookie的模式来实现用户的认证。即当一个注册用户通过登录操作请求后,Web服务器通过向数据库进行校验用户名和密码,通过后就会向Session中添加一条记录,然后返回给浏览器。在返回给浏览器的报文中,会将sessionId放在Cookie里头。

MyShop v1版本的访问操作

这样一来,用户在登录之后再访问网站的时候,就会将带有sessionId的Cookie传给Web服务器,而Web服务器就可以通过Cookie中的sessionId去Session记录中检查,如果没有过时就认为其是认证的活跃用户。

在ASP.NET Core中,提供了一个管理Session的中间件,我们可以在StartUp中注册和使用这个中间件即可用来管理会话状态。

参考资料:ASP.NET Core中的会话和状态管理,传送门:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/app-state?view=aspnetcore-3.1

2单块阶段(下)

v1版本上线测试之后,测试人员发现存在一个问题:登录用户会间歇性地退出登录,而且会话还没有超时。经过分析后发现,原来的Session记录只会在登录过的那台Web服务器上存在,而MyShop是以集群方式来部署的,由前置的Nginx代理服务器进行负载均衡地请求转发。

针对这个问题,MyShop设计了下图所示的v1.1版本的认证架构,又称为黏性Session架构。也就是说,不过哪一次请求,Nginx都会将对应的sessionId发给对应的Web服务器进行处理,而不是均衡地轮流转发。换句话说,Nginx服务器将会维护sessionId与各个Web服务器的Session之间的关联,以保证在会话期间的Session绑定。

MyShop v1.1版本-黏性会话

就这样,一晃两三年又过了,MyShop v1.1的认证架构支持了它早期的快速发展。但是,随着业务和用户量的不断扩展,它也逐渐暴露出稳定性和扩展性方面的问题。这些问题,归根结底还是由黏性会话所造成的。

(1)稳定性:黏性会话会将用户会话绑定到某个服务器上,如果我们要对这个服务器进行一些升级或改造又或服务器延迟或宕机,那么此服务器上的一波认证用户信息就会瞬间消失,用户必须重新登录。

(2)扩展性:黏性会话使得Web服务器和Nginx负载均衡服务器上都保存了状态,整体上属于一个有状态架构。随着流量的增长,这些状态同时给Web服务器和负载均衡器都会带来较大的压力。和无状态的应用架构比起来,这种有状态的应用架构比较难以扩展。

一般来说,常见的解决黏性会话的解决方案有以下几种:

(1)会话同步复制:即各个Web服务器之间同步Session,但是会引入复杂性,整体的性能较低。

(2)无状态会话:即Session数据不存在服务器端,而是存在浏览器端,但是存在数据泄露风险,且浏览器端对于Cookie的大小有限制(4KB)。

(3)集中状态会话:即将Session集中存储在某个存储中,比如Memcached或Redis这种高性能缓存中。

因此,MyShop选择了集中状态会话的方式演进出了v1.5安全认证架构,如下图所示:

MyShop v1.5版本-集中状态会话

在v1.5版本中,Web服务器和Nginx服务器不再存储会话状态,转而交由Redis进行统一存储,从而提高了稳定性和扩展性。对于Redis来说,也可以采用高可用集群方案,业界也有很多可扩展的实践案例。

画外音:虽然是单块时代发展出来的技术,但是无状态会话和集中状态会话却是微服务安全认证架构的基础。

3微服务架构阶段(上)

时光飞逝,时间来到了2015年,这期间MyShop的业务量也迅速的飞涨,期间互联网的技术也发生了大变化。微服务架构、无线应用、SPA应用雨后春笋般的出现,MyShop的技术团队也准备陆续应用实践,进一步丰富和扩展业务渠道,赋能业务端。但是,微服务架构的安全认证授权也存在着一些挑战:

微服务认证授权挑战

(1)后台应用和服务众多,如何对每一个服务进行认证和鉴权?传统的用户名&密码以及Session/Cookie的方式还能够适用吗?

(2)前端的用户入口众多,如果每个入口都搞一套登录认证,显然成本高且难以扩展。有没有一种SSO单点登录的方案?

经过MyShop技术团队的分析,传统的用户名&密码+Session/Cookie的方式无法直接套用在微服务架构上,但是可以借鉴之前的思路,他们提出了面向微服务架构的v2.0安全认证体系,如下图所示:

MyShop v2.0版本-基于Token的认证

v2.0安全认证体系最大的变化就在于,将登陆认证抽取为一个独立的API微服务AuthService,拥有一个独立的UserDB。这个服务统一承担登陆认证、用户校验、令牌颁发等职责。此外,v2.0版本还引入了Token作为服务调用认证鉴权的主要凭证。这里的话,v2.0采用的是一个透明令牌(也称为引用令牌),即它是一个无意义的随机字符串。这个令牌跟Auth Service上的一次登陆会话相关联,后续也可以通过API去校验这个令牌的合法性。

画外音:其实这个Token令牌,就相当于一个SessionId。每个微服务拿到令牌,都可以去AuthService进行认证鉴权。

总结下来,v2.0的安全认证体系的步骤如下:

Step1.用户通过某种客户端(Web/SPA/H5/App等)进行登陆,AuthService通过比对用户数据库进行校验;

Step2.AuthService校验通过后会建立一个用户会话Session(此Session和之前版本的类似,存在一个过期时间,可以存储在AuthService所在的服务器上也可以存在Redis中),然后颁发一个Token给客户端;

Step3.客户端向后台微服务发请求,会带上刚刚得到的Token;

Step4.微服务接收到用户请求时,首先会向AuthService发出一个请求对这个Token进行合法性校验;

Step5.AuthService校验Token通过后会返回该用户的详情信息(如果微服务需要的话,可以拿到用户的一些比如角色之类的信息);

Step6.微服务进行自己的逻辑处理,最终返回数据给客户端;

画外音:v2.0版本可以看做是v1.5的一个升级改造,专门针对微服务架构的场景进行了扩展,可以应对微服务架构存在的挑战。它把登录认证、令牌颁发等工作封装在了AuthService中,其他微服务统一共用AuthService,经过扩展还可以实现SSO单点登录。

4微服务架构阶段(下)

v2.0认证架构虽然可以解决问题,但是又引发了另外的问题:

首先,每个微服务都需要实现部分认证鉴权的逻辑,使得微服务开发方无法聚焦于业务逻辑的开发。

其次,认证鉴权逻辑分散在每个微服务当中,一方面会带来不规范容易出错的问题,另一方面也会有潜在的安全风险(比如某些开发人员可能会忘记校验令牌)。

为了解决上面提到的问题,同时考虑到微服务拆分后引入微服务API网关,MyShop技术团队设计了下图所示的v2.5认证架构:Token+Gateway结合方式

MyShop v2.5版本-基于Token+Gateway的认证

从上图可以看出,该架构将每个微服务都要进行的部分认证鉴权的逻辑从微服务转移到了网关中。即网关处负责拿到令牌向AuthService进行鉴权,通过后再将请求转发到后端的微服务,微服务不再包含任何认证鉴权的逻辑。

总体上,通过引入网关进行令牌的鉴权之后,大大减少了后端微服务开发方的职责,使得他们更专注于微服务的业务逻辑的开发。此外,引入网关之后,网关可以统一处理登录客户端的校验,也便于实现SSO单点登录,也为MyShop后续的微服务化和业务成长提供了基础。

画外音:v2.5版本应该是目前大多数团队所采用的一种认证架构了。对,我司也是,不过Token类型使用的是JWT。

5小结

本文通过一个MyShop的案例的演化介绍了微服务的安全认证架构是如何演进而来的,但是v2.5版本(Token+Gateway方式)总体上还是比较重,每个请求都还是需要到AuthService上去做认证鉴权的操作,这对于AuthService来说算是压力比较大。针对这个问题,业界广泛采用JWT这种轻量级的解决方案来重构安全认证架构。

那么问题来了,JWT是什么?原理?实现方式?下一期骚年快答,为你解答这几个问题。

往期骚年快答

技术中台与业务中台有啥联系?

微服务架构中的BFF到底是个啥?

为何微服务项目都爱用单体仓库?

专注于开发技术与个人成长分享,

对你有用的公众号!

????点个赞/在看如何?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maskrcnn还可以加网络吗_绿茶加蜂蜜的功效,绿茶可以加蜂蜜吗?

绿茶是我国的主要茶类之一,是一种天然健康的饮料,蜂蜜也是一种营养丰富的滋补食品,有些人不喜欢绿茶的苦味,想放点蜂蜜中和一下,但是不知道能不能这样做。那么绿茶能不能加蜂蜜呢?蜂蜜的主要成分是葡萄糖、果糖&#…

三分钟Docker-镜像、容器实战篇

本文主要内容:Docker 镜像、容器 常用命令整理使用Docker常见命令,搭建Consul集群通过创建自定义镜像,把.NetCore Api运行在Docker中1.镜像、容器命令镜像序号命令描述1docker image build基于Dockerfile创建镜像2docker image history显示镜…

手机键鼠映射软件_吃鸡,我最专业!---盖世小鸡键鼠吃鸡套装评测

Hello大家好,欢迎浏览这篇评测贴。首先很荣幸能够参与本期的评测,毕竟如此炫酷富有科技感的装备是可遇而不可求的,所以不论是得知入选还是收到快递开箱的时候,心情都是无比激动。话不多说,接下来就让我带你走进这个不一…

[Redis6]Redis启动_前台启动和后台启动

前台启动(不推荐) 前台启动,命令行窗口不能关闭,否则服务器停止 redis-server 关闭redis ctrlC : 关闭 后台启动(推荐) 备份redis.conf cd redis-6.2.6/cp redis.conf /etc/redis.confcd /etc后台启动设置daemonize no改成y…

深入剖析.NETCORE中CORS(跨站资源共享)

前言由于现代互联网的飞速发展,我们在开发现代 Web 应用程序中,经常需要考虑多种类型的客户端访问服务的情况;而这种情况放在15年前几乎是不可想象的,在那个时代,我们更多的是考虑怎么把网页快速友好的嵌套到服务代码中…

ai进入轮廓模式怎么退出_详解AI中扩展、扩展外观、轮廓化描边、创建轮廓

详解AI中扩展、扩展外观、轮廓化描边、创建轮廓在学习AI软件中,有不少同学分不清扩展、扩展外观、轮廓化描边、创建轮廓这四个概念具体的功能区别,今天我们具体聊一下。先说“扩展”,扩展是把复杂物体拆分成最基本的路径。矢量物体在组合&…

[Redis6]Redis相关知识介绍

Redis介绍相关知识 端口6379 6379 是 "MERZ " 九宫格输入法对应的数字。Alessia Merz 是一位意大利舞女、女演员。 Redis 作者 Antirez 早年看电视节目,觉得 Merz 在节目中的一些话愚蠢可笑,Antirez 喜欢造“梗”用于平时和朋友们交流&#x…

【Power Automate】如何自动生成Word与PDF文件[上]

上半年已经悄悄溜走,因为疫情,大家似乎也很习惯于在家办公。作为业务人员,如何汇报自己的工作,让自己更多地学习和掌握数字化办公技巧至关重要。那么今天我们就来看一下在不使用代码的情况下,如何通过Power Automate自…

easyui datagrid 中怎么选中所有页面的数据_学会这5个Excel中常用技巧,可以准时下班去摆摊了...

Excel是大家常用的办公工具之一,虽说上手简单,但是想要精通还是要下一些功夫的。最近有些小伙伴在留言吐槽说Excel数据处理时很方便,但是操作起来还是挺费时间的,其实工作是离不开技巧的,今天要跟大家分享的5个Excel技…

五年了,别再把务虚会开 “虚” 了

这是头哥侃码的第210篇原创上个月,为了配合公司的半年度战略讨论会,我特意留出一个周六的时间,与几位Leader在公司的会议室里开了一次部门半年度务虚会。让我没想到的是,几位小伙伴在这次讨论过程中都表现得非常亢奋,所…

人工智能正在如何改变传统行业

做了这么多年的技术工作,也正好赶上了这一波的人工智能浪潮,有时候我总是不免在想,人工智能如何真正地融入到我们的日常工作和生活中,实现它应有的价值。大家可能不知道,人工智能其实最早在上个世纪五十年代就提出来了…

[Redis6]key键操作

我们先连接redis cd /usr/local/bin/ redis-cliRedis键(key) keys *查看当前库所有key (匹配:keys *1) exists key判断某个key是否存在 type key 查看你的key是什么类型 del key 删除指定的key数据 unlink key 根据value选择非阻塞删除 仅将keys从keyspace元数据…

继续分享 5 个实用的 vs 调试技巧

前言我在上一篇文章????《5 个非常实用的 vs 调试技巧》 中分享了 5 个我认为非常值得了解的 vs 调试技巧,本周继续分享 5 个很基础但同样实用的调试技巧。1. 条件断点作用简介:顾名思义,带条件的断点。满足条件才中断。条件断点非常非常…

[Redis6]常用数据类型_String字符串

Redis字符串(String) 简介 String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。String类型是Redis最基本的数据…

在ASP.NET Core中创建自定义端点可视化图

在上篇文章中,我为构建自定义端点可视化图奠定了基础,正如我在第一篇文章中展示的那样。该图显示了端点路由的不同部分:文字值,参数,动词约束和产生结果的端点:在本文中,我将展示如何通过创建一…

[Redis6]常用数据类型_List列表

List列表 简介 单键多值 Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 它的底层实际是个双向链表,对两端的操作性能很高,通过索…

[Redis6]常用数据类型_Set集合

Set集合 简介 Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个s…

来领.NET Core学习资料,7天整理了30多个G(适合各阶段.Net开发者)

干货分享2020/07/27大家好,我是CSDN的小黑,2020年的唯一跳槽季,金九银十马上到来,今天这波干货必须学习起来!前后整理了半个月,从零基础到就业,进阶高级开发,走向架构,三…

[Redis6]常用数据结构_Hash哈希

Hash哈希 简介 Redis hash 是一个键值对集合。 Redis hash是一个string类型的field和value的映射表&#xff0c;hash特别适合用于存储对象。 类似Java里面的Map<String,Object> 用户ID为查找的key&#xff0c;存储的value用户对象包含姓名&#xff0c;年龄&#xff…

ASP.NET Core中的分布式缓存

ASP.NET Core中的分布式缓存在上一篇文章中[1]&#xff0c;我解释了如何使用内存缓存在ASP.NET Core应用程序中管理缓存。如果您的应用程序托管在单个服务器上&#xff0c;则可以使用这种类型的缓存。那.NET Core框架可以使用哪些工具在云中的分布式方案中进行缓存呢IDistribut…