你没见过的分布式系统认证方案!

2,112 阅读8分钟

一、分布式系统的特点

  • 分布性:每个部分都可以独立部署,服务之间交互通过网络进行通信,比如:订单服务、商品服务
  • 伸缩性:每个部分都可以集群方式部署,并可针对部分结点进行硬件及软件扩容,具有一定的伸缩能力
  • 共享性:每个部分都可以作为共享资源对外提供服务,多个部分可能有操作共享资源的情况。
  • 开放性:每个部分根据需求都可以对外发布共享资源的访问接口,并可允许第三方系统访问。

二、分布式认证需求

分布式系统的每个服务都会有认证、授权的需求,如果每个服务都实现一套认证授权逻辑会非常冗余,考虑分布式系统共享性的特点,需要由独立的认证服务处理系统认证授权的请求;考虑分布式系统开放性的特点,不仅对系统内部服务提供认证,对第三方系统也要提供认证。分布式认证的需求总结如下:

①统一认证授权

提供独立的认证服务,统一处理认证授权。

无论是不同类型的用户,还是不同种类的客户端(web端, H5APP),均采用一致的认证、权限、会话机制,实现统一认证授权。要实现统一则认证方式必须可扩展,支持各种认证需求,比如:用户名密码认证、短信验证码、二维码、人脸识别 等认证方式,并可以非常灵活的切换。

②应用接入认证

应提供扩展和开放能力,提供安全的系统对接机制,并可开放部分 API给接入第三方使用,一方应用(内部系统服务)和三方应用(第三方应用)均采用统一机制接入。

三、分布式认证方案

3.1基于 session 的认证方式

在分布式的环境下,基于 session的认证会出现一个问题,每个应用服务都需要在 session中存储用户身份信息,通 过负载均衡将本地的请求分配到另一个应用服务需要将 session信息带过去,否则会重新认证。 这个时候,通常的做法有下面几种:

  • Session复制:多台应用服务器之间同步 session,使 session保持一致,对外透明。
  • Session黏贴:当用户访问集群中某台服务器后,强制指定后续所有请求均落到此机器上。
  • Session集中存储:将 Session存入分布式缓存中,所有服务器应用实例统一从分布式缓存中存取 Session

3.2 基于 token 的认证方式

基于 token的认证方式,服务端不用存储认证数据,易维护扩展性强, 客户端可以把 token存在任意地方,并且可 以实现web和app统一认证机制。其缺点也很明显, token由于自包含信息,因此一般数据量较大,而且每次请求 都需要传递,因此比较占带宽。另外, token的签名验签操作也会给 cpu带来额外的处理负担。

3.3 选用方案

根据选型的分析,决定采用基于 token的认证方式,它的优点是:

  1. 适合统一认证的机制,客户端、一方应用、三方应用都遵循一致的认证机制
  2. token认证方式对第三方应用接入更适合,因为它更开放,可使用当前有流行的开放协议 Oauth2.0JWT
  3. 一般情况服务端无需存储会话信息,减轻了服务端的压力

四、分布式认证流程

  1. 用户通过接入方(应用)登录,接入方采取 OAuth2.0方式在统一认证服务(UAA)中认证。
  2. 认证服务(UAA)调用验证该用户的身份是否合法,并获取用户权限信息。
  3. 认证服务(UAA)获取接入方权限信息,并验证接入方是否合法。
  4. 若登录用户以及接入方都合法,认证服务生成 jwt令牌返回给接入方,其中 jwt中包含了用户权限及接入方权 限。
  5. 后续,接入方携带 jwt令牌对API网关内的微服务资源进行访问。
  6. API网关对令牌解析、并验证接入方的权限是否能够访问本次请求的微服务。
  7. 如果接入方的权限没问题, API网关将原请求header中附加解析后的明文 Token,并将请求转发至微服务。
  8. 微服务收到请求,明文 token中包含登录用户的身份和权限信息。因此后续微服务自己可以干两件事:①用户授权拦截(看当前用户是否有权访问该资源)②将用户信息存储进当前线程上下文(有利于后续业务逻辑随时获取当前用户信息)

4.1 统一认证服务(UAA)

它承载了 OAuth2.0接入方认证、登入用户的认证、授权以及生成令牌的职责,完成实际的用户认证、授权功能

4.2 API 网关

作为系统的唯一入口, API网关为接入方提供定制的 API集合,它可能还具有其它职责,如身份验证、监控、负载均衡、缓存等。 API网关方式的核心要点是,所有的接入方和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。

五、OAuth2.0 介绍

OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不 需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。 OAuth2.0OAuth协议的延续版本,但不向后兼容 OAuth 1.0即完全废止了 OAuth1.0。很多大公司如 GoogleYahooMicrosoft等都提供了 OAUTH认证服务,这些都足以说明 OAUTH标准逐渐成为开放资源授权的标准。

5.1 OAuth2.0 使用案例

下边分析一个 Oauth2认证的例子,通过例子去理解 OAuth2.0协议的认证流程,本例子是黑马程序员网站使用微信认证的过程,这个过程的简要描述如下:

①客户端请求第三方授权

用户进入斗鱼的登录页面,点击微信的图标以 QQ账号登录系统,用户是自己在 QQ里信息的资源拥有者。 ②资源拥有者同意给客户端授权

点击 QQ开始给斗鱼授权,资源拥有者登录 QQ表示资源拥有者同意给客户端授权, QQ会对资源拥有者的身份进行验证, 验证通过后, QQ会询问用户是否给授权斗鱼访问自己的 QQ数据,用户点击"确认登录"表示同意授权, QQ认证服务器会颁发一个授权码,并重定向到斗鱼的网站。 ③客户端获取到授权码,请求认证服务器申请令牌

此过程用户看不到,客户端应用程序请求认证服务器,请求携带授权码。

④认证服务器向客户端响应令牌

QQ认证服务器验证了客户端请求的授权码,如果合法则给客户端颁发令牌,令牌是客户端访问资源的通行证。 此交互过程用户看不到,当客户端拿到令牌后,用户在斗鱼看到已经登录成功。

⑤客户端请求资源服务器的资源

客户端携带令牌访问资源服务器的资源,斗鱼网站携带令牌请求访问QQ服务器获取用户的基本信息。

⑥资源服务器返回受保护资源

资源服务器校验令牌的合法性,如果合法则向用户响应资源信息内容

5.2 认证授权执行流程

通过上边的例子我们大概了解了 OAauth2.0的认证过程,下边我们看 OAuth2.0认证流程:
OAauth2.0包括以下角色:

①客户端 本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如: Android客户端、 Web客户端(浏 览器端)、微信客户端等。

②资源拥有者 通常为用户,也可以是应用程序,即该资源的拥有者。

③授权服务器(也称认证服务器) 用于服务提供商对资源拥有的身份进行认证、对访问资源进行授权,认证成功后会给客户端发放令牌( access_token),作为客户端访问资源服务器的凭据。本例为微信的认证服务器。

④资源服务器 存储资源的服务器,本例子为QQ存储的用户信息。 现在还有一个问题,服务提供商能允许随便一个客户端就接入到它的授权服务器吗?答案是否定的,服务提供商会给准入的接入方一个身份,用于接入时的凭据: client_id:客户端标识; client_secret:客户端秘钥

因此,准确来说,授权服务器对两种 OAuth2.0中的两个角色进行认证授权,分别是资源拥有者、客户端。