摘要. 随着市场和业务的不断扩大, 传统的单一整体架构面临着越来越多的挑战。云计算和容器技术的发展促进了微服务架构变得越来越流行。尽管微服务体系结构的低耦合,细粒度,可伸缩性,灵活性和独立性带来了方便,但分布式系统的固有复杂性使得微服务体系结构的安全性变得重要和困难。本文旨在研究在微服务架构下最终用户的认证和授权。通过与传统方法的比较和现有技术的研究,提出了一套适用于微服务体系结构的认证和授权策略,如分布式会话,SSO解决方案,客户端JSON Web Token和JWT + API Gateway,并总结每种方法的优缺点。
1. 介绍
对于任何成熟的系统,最终用户模块的完整认证和授权至关重要。它保护系统的边界。认证和授权有什么区别? 验证是验证你是谁的过程。当您使用用户名和密码登录到PC时,您正在进行身份验证。授权是验证您有权访问某个内容的过程。例如,一些资源只允许管理员查看,而不是普通用户。
1.1 单片应用程序中的验证
在传统的单一体系结构项目中,用户的请求在后端的单个进程中处理。在系统边界放置一个过滤器来验证身份和访问权限,并确定请求的响应或分发。由于HTTP是无状态协议,它通常基于服务器为客户端生成的会话来管理用户的状态。
这是会话控制过程:
1. 客户端提供认证凭证。
2. 服务器验证凭据:验证失败时重新认证;如果验证成功,则生成会话。
3. 客户端通过会话请求资源
4. 如果用户有权访问,则服务器通过会话和响应资源获取用户会话
基于会话的系统的优点很容易实现,并且对系统的入口更少。但也有许多挑战。服务器需要将会话保存在内存中,这可能会导致较高的内存使用量并降低性能。另一方面,身份验证功能和其他系统的功能混合在一起,耦合度高,降低了系统的可扩展性和灵活性。随着流量的增加,系统需要部署多个节点才能实现负载均衡。在多个节点中共享会话是一个问题。此外,基于会话的系统大多数时候都使用cookie,所以它应该处理来自客户端的一些基于cookie的攻击。
1.2 分布式会话管理
随着系统功能变得越来越复杂,用户数量增加,部署在单机上的应用程序无法应对压力。从单个节点到群集,多个节点在使用基于会话的身份验证时必须共享一个会话。关于分布式粘滞会话,会话复制,会话集中管理等方面存在一些解决方案。
粘滞会话确保所有后续请求都将发送给处理与该请求相对应的第一个请求的服务器。会话复制意味着每个服务器都保存会话数据,并通过网络进行同步。所以它会受到网络情况的影响。集中管理添加了一个特定的服务器来管理会话。来自会话服务器的每个服务请求会话。
无论如何,分布式会话设计复杂且难以维护。
1.3 Token-Based Auth
基于令牌的认证系统允许用户输入他们的用户名和密码,以获得令牌,使他们能够在不使用用户名和密码的情况下获取特定资源。一旦获得他们的令牌,用户可以提供令牌访问特定资源一段时间到远程站点。
通过使用令牌,不需要保留会话存储; 令牌是传递所有用户信息的独立实体。另外,令牌是无状态的,所以处理服务器端可扩展性很容易。令牌适用于浏览器和移动设备等不同的客户端。同时,它可以有效避免CORS和CSRF攻击。
图1 Token-based 认证
2. 微服务中的身份验证挑战
2.1 什么是微服务体系结构
虽然没有标准的微服务正式定义。用Fowler&Lewis的话来说,微服务是一种将单个应用程序作为一套小型服务开发的方法,每个小应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。我们喜欢微服务出于一系列原因有撰写功能、独立服务、“有界的上下文”、独立缩放、独立部署、本地化故障、倾向无状态、不依赖于HTTP会话。
2.2微服务中的身份验证服务
有一种简单的方法来处理微服务中的认证和授权,即模仿单片结构的方式。每个服务使用自己的数据库或共享数据库来存储凭证数据并实现自己的功能来独立验证用户。这种方式很容易理解,但有几个缺陷。首先,每次在系统中加入新服务时,都必须重新实现新服务的身份验证功能。其次,当我们使用单个共享用户数据库时,它将具有单点故障问题。而且,这种方式违背了微服务的单一责任原则。
为了改进上述体系结构并适应微服务设计原则,我们在系统中放置了一个单独的auth服务, auth服务侧重于用户的身份验证和授权。其他服务通过与auth服务交互来验证用户的身份和权限。因此,每项服务都专注于自己的业务,同时提高系统的可扩展性和松耦合性。
2.3 我们想要什么
安全:安全意味着用户有安全的身份。根据我们实际部署系统的方式,微服务中的信息共享可能是一个问题。
无状态服务:我们希望运行多个实例的无状态服务,因为我们正在部署云,任何事情都可能随时失败。
没有单点故障:如前一节所述,共享数据库解决方案存在SPOF问题。
没有固有的瓶颈、能够注销、与微服务集成、易于实施。
3. 使用分发会话
在第一部分中,我们提到了传统的基于会话的认证和授权方法以及分布式会话管理。众所周知,微服务是分布式体系结构。本节介绍如何在微服务中实施分发会话解决方案。
用户请求访问某些服务,如果请求中没有sessionid,服务将重定向到auth服务器。Auth要求用户提供凭证,为用户生成会话并将其存储在会话存储中,然后将sessionid返回给用户。用户使用sessionid重新请求访问服务。使用sessionid查询会话存储以获取用户状态并进行适当的响应。
如第一部分所述,分发会话解决方案是可行的,但实现起来并不复杂。接下来将介绍几种基于令牌的解决方案,包括微服务中的认证和授权。
4. 使用 JSON Web Token
4.1. JSON Web Token(JWT)
JSON Web Token(JWT)是基于开放标准(RFC 7519)的信息传输协议,由标头,有效载荷和签名组成。
1. 头部:头部通常由两部分组成,其中一部分是令牌类型,即JWT,另一部分是使用的哈希算法,例如HMAC SHA256或RSA。JSON的格式
头部格式如下:
{ "alg": "HS256",
"typ": "JWT"}
然后,这个JSON被Base64Url编码,形成JWT的第一部分。
2. 有效负载:由索赔组成的令牌的第二部分。声明是关于实体的声明
(通常是用户)和补充元数据。
{ "exp": 1494428560,
"name": "John Doe",
"authorities": [
"ROLE_ADMIN",
"VIEW_RESOURCE"]
…}
然后将有效载荷Base64Url进行编码以形成JSON Web令牌的第二部分。
3. 签名:本节将根据标题部分中指定的算法对Header和Payload部分进行签名,以防止恶意修改。
例如,如果您想使用HMAC SHA256算法,则签名将按以下方式创建:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
4.2. 客户端JWT解决方案
当用户向资源服务器发送请求时,如果没有令牌或令牌过期,资源服务器将重定向到auth服务器。用户将凭证发送给auth服务器。Auth服务器验证凭证并为包含用户权限,过期时间等的用户生成JWT令牌。用户此次用JWT令牌重新请求资源服务器。资源服务器解码令牌并验证用户权限。然后做出适当的回应。由于签名,JWT可以验证自己,而不是请求auth服务器。所以这将减少auth服务器压力和流量。另一个好处是系统很容易扩展为令牌无状态。
迄今为止这是一个很好的解决方案。但是如何注销。我们知道JWT包含到期时间。在到期之前,令牌总是有效的。当我们想要注销时,最简单的方法就是从客户端删除令牌。但这不是安全的,因为服务器端并不知道。
5. 使用JWT + API网关
在微服务体系结构中,我们可以发现系统边界存在一个API网关。API网关跨一个或多个内部API提供单一的统一API入口点。
注销最重要的是使服务器端的令牌无效。由于每个请求都会经过API网关,因此我们可以使用它来解决注销问题。关键的一步是API网关将JWT转换为不透明的令牌。
JWT + API网关解决方案的大多数步骤与V中的解决方案相同。唯一的区别是网关已传输令牌。Auth服务器为用户生成一个JSON Web令牌并将其传递给网关。网关将令牌转移到只有自己可以解决的不透明令牌。然后将不透明令牌和原始令牌的关系存储在令牌存储中,并将不透明令牌发送给客户端。当网关收到来自客户端的不透明令牌时,将其转移给原始令牌,然后将原始令牌转发给资源服务。通过该转移步骤,我们可以删除API网关令牌存储中的令牌关系,因此客户端需要重新请求令牌。这是注销问题的绝妙解决方案。
通过与传统的单片架构进行比较,本文探讨了微服务架构中的几种认证和授权解决方案。分布式会话解决方案与传统的认证方式类似,但其实现和维护的复杂性较高。SSO服务器将导致SPOF和流量问题。使用API网关改进客户端JWT解决方案可以解决注销问题。所以没有绝对正确的解决方案,但只有适合您的系统的选项。