传统单体项目拆分成微服务之后,微服务之间的安全性应该如何保证。比如应该怎样确保对某个微服务的远程调用,不会是他人冒充,仅仅通过服务注册中心维护就安全了吗。要知道,在互联网上传输的数据没有绝对的安全,奥巴马在贝爷的节目里还说不敢使用手机呢。当然,全部微服务部署在同一个局域网内,对外网只暴露网关,应该是一种不错的选择。也就是说,可以利用局域网技术,对外网屏蔽服务注册中心,只能通过内网进行服务注册,在内网进行微服务的治理与管理。服务注册中心拥有无比的重要性,因为微服务间的调用就是通过服务注册中心进行协调。容器技术的发展,也让这一想法也了更多的实践机会。比如使用kubernetes,可以轻松达到微服务间的私有云访问。
但是这样,一个新的问题紧跟着而来。一个不在同一个微服务系统的第三方应用程序,想要访问本微服务系统数据或者使用特定的功能,如何处理?说的通俗点,就是提供第三方接口。第三方接口很常见,用户量稍多的互联网软件,都会提供,比如QQ、微博、微信等的第三方登录。因为是第三方接口,所以必须提供一个外网可访问的授权中心。因此,授权中心应该对外网开放,不会被屏蔽在内网中。
在微服务即分布式系统中,授权中心究竟是应该统一还是分散,网上的说法比较倾向统一。因为分散意味着维护的难度,开发的难度加大。软件不是开发完功能就一成不变的死东西,伴随着时间的推移,软件的功能复杂度会逐渐增加。不要看微信几年了没什么变化,不变的表面背后是多少改变。小程序、第三方功能入口、公众号打赏等等一些看起来平淡无奇的功能,都是需要升级维护的。如果不升级维护,代码很容易出现腐化的味道,到最后烂掉。
既然实现了第三方登录,登录后的第三方系统,就可以对全部网关数据进行无障碍访问吗?答案很明显是NO。如果这样,第三方系统就成了该微服务系统的一份子,全部资源数据透明可见,那就是很明显的安全漏洞了。有些人会说,不把网关的API接口暴露给第三方程序,不就行了吗?这种想法很天真,天底下没有不透风的墙,能在互联网传输的就没有绝对的安全。
所以需要一种机制,限定第三方系统的访问权限,不能访问的数据,打死也访问不了。因为HTTP的无状态,第三方系统每次访问服务器都要附带授权信息,这样服务器才能识别访问者的身份。如果要实现安全级别较高的第三方授权登录,还可以使用安全证书(微信支付)或者非对称加密(支付宝支付)进行处理。
除了第三方系统授权登录,确保系统本身的用户登录使用才是最基本的。用户类型很多,一般有后台管理员与会员两大类。后台管理员,又可根据系统的情况,分为具有全部操作权限的超级管理员,负责某个模块功能的系统管理员、只能进行特定操作的普通操作员。为了刺激用户的活跃性,会员自然需要分等级处理。不同等级的会员,会有不同的使用特权。普通操作的会员,自然不会出现越级使用特权的情况。但是还存在另外一种由计算机自动控制的会员,即通常意义说机器人。对于这些机器人,操作界面的限制将不再是限制,服务器开放接口数量,才是真正的限制。就是说,如果没有一定的检查逻辑,机器人越级使用会员等级的特权,就像喝水一样平常。
到了这里,已经出现三类系统的使用者——第三方接口调用者、后台管理员、会员。但是仅仅只是这三种吗,估计不会。就像自然界,不只生存着人类。虚拟世界的互联网技术,越来越朝着向自然界拟人化的方向发展。会出现哪种使用者,很大程度要看系统的功能而定。如果从大的时间跨度上看待一个系统,使用的用户类型肯定是多种多样,就像王朝的兴衰更替。但是选取其中一个时间点前后一段时间,系统的用户类型又是固定的。
既然预知了有这种变化,如何使系统做到弹性扩展呢。众所周知,系统的横向扩展,比纵向扩展简单得多。数据库方面的集群,就是不断添加新机器,保证集群的响应时间不会随着数据量过多而降低。微服务的出现,就是向横向扩展提供基础。
但是这也意味着微服务与微服务之间,存在明显的隔阂。最简单的例子,如果java开发的web服务器使用传统的session会话,单个微服务保存的用户上下文,一般无法在其他微服务使用。如何解决微服务下用户会话的统一,网上出现了很多种方法,目前了解的主要有两种。一种是把用户会话信息统一存储,统一读取,存储的地方可使用关系型或者非关系型数据库。数据库选择的标准不多,支持大数据量的快速响应是首选。另外一种是利用HTTP的无状态,使用特定加密方法加密用户信息,然后存储在HTTP请求头中,即一般说的token验证。
这两种方法各有优劣,取舍看实际情况而定。如果是旧系统升级改造,推荐第一种方法,因为对代码的改动比较小。但是第一个方法,引入了额外的数据库,因为需要专门的数据库储存用户会话信息,还要处理会话过期数据。相反,第二种方法则不需要专门的数据库,只需要特定的加密解密方法。但是第二种方法,也有比较麻烦的地方。加密的用户信息,一般不会使用全部的用户信息。如果token信息被破解,使用全部的用户信息不就暴露无遗了吗?所以个人觉得使用用户对应的数据库id与登录名即可完成加密。解密后,如果需要特定权限操作的地方,可以根据数据库id与用户名再次获取用户权限,进行权限判断。如果这样的话,可以配合API网关,进行统一鉴权处理。这时的API网关,同时扮演着前置机的角色。
不过这样的系统,就跟一些人说的微服务各自自己治理自己,各自进行演化的概念有点出入。正确的理解应该是微服务在保持一致秩序下,各自自己治理自己,各自进行演化。
网友评论