微服务架构下的鉴权,怎么做更优雅?

作者:王海龙
来源:微信公众号EAWorld
https://mp.weixin.qq.com/s/x0CZpovseouofTA_lw0HvA
从单体应用架构到分布式应用架构再到微服务架构,应用的安全访问在不断的经受考验 。为了适应架构的变化、需求的变化,身份认证与鉴权方案也在不断的变革 。面对数十个甚至上百个微服务之间的调用,如何保证高效安全的身份认证?面对外部的服务访问,该如何提供细粒度的鉴权方案?本文将会为大家阐述微服务架构下的安全认证与鉴权方案 。
一、单体应用 VS 微服务随着微服务架构的兴起,传统的单体应用场景下的身份认证和鉴权面临的挑战越来越大 。单体应用体系下,应用是一个整体,一般针对所有的请求都会进行权限校验 。请求一般会通过一个权限的拦截器进行权限的校验,在登录时将用户信息缓存到 session 中,后续访问则从缓存中获取用户信息 。
微服务架构下的鉴权,怎么做更优雅?

文章插图
 
而微服务架构下,一个应用会被拆分成若干个微应用,每个微应用都需要对访问进行鉴权,每个微应用都需要明确当前访问用户以及其权限 。尤其当访问来源不只是浏览器,还包括其他服务的调用时,单体应用架构下的鉴权方式就不是特别合适了 。在为服务架构下,要考虑外部应用接入的场景、用户 - 服务的鉴权、服务 - 服务的鉴权等多种鉴权场景 。
微服务架构下的鉴权,怎么做更优雅?

文章插图
 
David Borsos 在伦敦的微服务大会上提出了四种方案:
1. 单点登录(SSO)这种方案意味着每个面向用户的服务都必须与认证服务交互,这会产生大量非常琐碎的网络流量和重复的工作,当动辄数十个微应用时,这种方案的弊端会更加明显 。
2. 分布式 Session 方案分布式会话方案原理主要是将关于用户认证的信息存储在共享存储中,且通常由用户会话作为 key 来实现的简单分布式哈希映射 。当用户访问微服务时,用户数据可以从共享存储中获取 。在某些场景下,这种方案很不错,用户登录状态是不透明的 。同时也是一个高可用且可扩展的解决方案 。这种方案的缺点在于共享存储需要一定保护机制,因此需要通过安全链接来访问,这时解决方案的实现就通常具有相当高的复杂性了 。
3. 客户端 Token 方案令牌在客户端生成,由身份验证服务进行签名,并且必须包含足够的信息,以便可以在所有微服务中建立用户身份 。令牌会附加到每个请求上,为微服务提供用户身份验证,这种解决方案的安全性相对较好,但身份验证注销是一个大问题,缓解这种情况的方法可以使用短期令牌和频繁检查认证服务等 。对于客户端令牌的编码方案,Borsos 更喜欢使用 JSON Web Tokens(JWT),它足够简单且库支持程度也比较好 。
4. 客户端 Token 与 API 网关结合这个方案意味着所有请求都通过网关,从而有效地隐藏了微服务 。在请求时,网关将原始用户令牌转换为内部会话 ID 令牌 。在这种情况下,注销就不是问题,因为网关可以在注销时撤销用户的令牌 。
二、微服务常见安全认证方案HTTP 基本认证HTTP Basic Authentication(HTTP 基本认证)是 HTTP 1.0 提出的一种认证机制,这个想必大家都很熟悉了,我不再赘述 。HTTP 基本认证的过程如下:
  • 客户端发送 HTTP Request 给服务器 。
  • 因为 Request 中没有包含 Authorization header,服务器会返回一个 401 Unauthozied 给客户端,并且在 Response 的 Header "WWW-Authenticate" 中添加信息 。
  • 客户端把用户名和密码用 BASE64 加密后,放在 Authorization Header 中发送给服务器,认证成功 。
  • 服务器将 Authorization Header 中的用户名密码取出,进行验证,如果验证通过,将根据请求,发送资源给客户端 。
基于 Session 的认证