微服务架构下的安全认证与鉴权

从单体应用架构到分布式应用架构再到微服务架构,应用的安全访问在不断地经受考验。为了适应架构的变化、需求的变化,身份认证与鉴权方案也在不断地变革。面对数十个甚至上百个微服务之间的调用,如何保证高效安全的身份认证是个难题。面对外部的服务访问,如何提供细粒度的鉴权方案也是个难题。数据库

单体应用VS微服务跨域

随着微服务架构的兴起,传统的单体应用场景下的身份认证和鉴权面临的挑战愈来愈大。浏览器

在单体应用体系下,应用是一个总体,通常针对全部的请求都会进行权限校验。请求通常会经过一个权限的拦截器进行权限的校验,在登录时将用户信息缓存到Session中,后续访问则从缓存中获取用户信息。缓存

而在微服务架构下,一个应用会被拆分红若干个微应用,每一个微应用都须要对访问进行鉴权,每一个微应用都须要明确当前访问用户以及其权限。尤为是当访问来源不仅是浏览器,还包括其余服务的调用时,单体应用架构下的鉴权方式就不是特别合适了。在微服务架构下,要考虑外部应用接入的场景、用户-服务的鉴权、服务-服务的鉴权等多种鉴权场景。安全

David Borsos在伦敦的微服务大会上提出了四种方案:服务器

1.单点登录(SSO)。这种方案意味着,每一个面向用户的服务都必须与认证服务交互,会产生大量很是琐碎的网络流量和重复的工做,当动辄数十个微应用时,这种方案的弊端会更加明显。微信

2.分布式Session方案。分布式会话方案的原理主要是讲关于用户认证的信息存储在共享存储中,且一般由用户会话做为key来实现的简单分布式哈希映射。当用户访问微服务时,用户数据能够从共享存储中获取。在某些场景下,这种方案很不错,用户登录状态是不透明的。同时也是一个高可用且可扩展的解决方案。这种方案的缺点在于,共享存储须要必定的保护机制,所以须要经过安全连接来访问,这时解决方案的实现就一般具备至关高的复杂性了。网络

3.客户端Token方案。令牌(Token)在客户端生成,由身份验证服务进行签名,而且必须包含足够的信息,以即可以在全部的微服务中创建用户身份。令牌会附加到每一个请求上,为微服务提供用户身份验证,这种解决方案的安全性相对较好,可是身份验证的注销是一个大问题,缓解这种状况的方法可使用短时间令牌和频繁检查认证服务等。对于客户端令牌的编码方案,Borsos更喜欢使用JSON Web Tokens(JWT),它足够简单,且库支持程度也比较好。架构

4.客户端Token与API网关结合。这个方案意味着全部的请求都会经过网关,从而有效地隐藏了微服务。在请求时,网关将原始用户令牌转换为内部会话ID令牌。在这种状况下,注销就不是问题,由于网关能够在注销时撤销用户的令牌。负载均衡

微服务常见安全认证方案

微服务常见安全认证方案主要由三种:HTTP基本认证、基于Session的认证和基于Token的认证。

HTTP基本认证(HTTP Basic Authentication)

HTTP基本认证是HTTP1.0提出的一种认证机制,过程以下:

1.客户端发送HTTP Request给服务器。

2.由于Request中并无包含Authorization Header,服务器就会返回一个401 Unauthozied给客户端,而且在Response的Header的【WWW-Authenticate】属性中添加信息。

3.客户端把用户名和密码用BASE64加密后,放在Authorization Header中发送给服务器,认证成功。

4.服务器将Authorization Header中的用户名和密码取出,进行验证,若是验证经过,将根据请求,发送资源给客户端。

基于Session的认证

基于Session的认证应该是最经常使用的一种认证机制了。用户登录认证成功后,将用户相关数据存储到Session中。单体应用架构中,默认Session会存储在应用服务器中,而且将SessionID返回到客户端中,存储到浏览器的Cookie中;分布式架构中,Session存放于某个具体的应用服务器天然是没法知足使用,简单的能够经过Session复制或Session粘滞的方案来解决。

Session复制依赖于应用服务器,须要应用服务器有Session复制能力,不过如今大部分应用服务器如Tomcat、JBoss和WebSphere等都提供了这个能力。

除此以外,Session复制的一大缺陷在于,当节点数比较多时,大量的Session数据复制会占用较多的网络资源。Session粘滞是经过负载均衡器,将统一用户的请求都分发到固定的服务器节点上,这样就保证了对某一个用户而言,Session数据始终是正确的。不过这种方案依赖于负载均衡器,而且只能知足水平扩展的集群场景,没法知足应用分割后的分布式场景。

在微服务架构下,每一个微服务拆分的粒度会很细,而且不仅有用户和微服务打交道,更多的还有微服务之间的调用。这个时候,上述两个方案都没法知足,就要求必需要将Session从应用服务器中剥离出来,存放在外部进行集中管理。能够是数据库,也能够是分布式缓存,好比Memchached、Redis等。这正是David Boros建议的第二种方案:分布式Session方案。

基于Token的认证

随着Restful API、微服务的兴起,基于Token的认证如今已经愈来愈广泛。Token和SessionID不一样,并不是只是一个key。Token通常会包含用户的相关信息,经过验证Token就能够完成身份校验。像Twitter、微信、QQ、Github等公有服务的API都是基于这种方式进行认证的,一些开发框架如OpenStack、Kubernates内部API调用也是基于Token认证。基于Token认证的一个典型流程以下:

1.用户输入登录信息(或者调用Token接口,传入用户信息),发送到身份认证服务进行认证(身份认证服务能够和服务端在一块儿,也能够分离,看微服务拆分状况)。

2.身份认证服务验证登录信息是否正确,返回Token(通常Token中会包含用户基础信息、权限范围、有效时间等信息),客户端存储Token,能够存储在Session或者数据库中。

3.用户将Token放在HTTP请求头中,发起相关API调用。

4.被调用的微服务,验证Token权限。

5.服务端返回相关资源和数据。

基于Token认证的好处

1.服务端无状态。Token机制在服务端不须要存储Session信息,由于Token自身包含了全部用户的相关信息。

2.性能较好。由于在验证Token的时候不用再去访问数据库或者远程服务进行权限校验,天然能够提高很多性能。

3.支持移动设备。

4.支持跨程序调用。Cookie是不容许跨域访问的,而Token则不会存在这个问题。

 

转自:https://mp.weixin.qq.com/s/x0CZpovseOuofTA_lw0HvA

"我历来没有被谁捧在手内心真正地爱过,每一次我都好像在克制本身,不要发脾气,要懂事,但是只有我本身知道,我有多么难过,多么心累。"

相关文章
相关标签/搜索