微服务架构中的身份验证和授权 - 第一部分
关于Behalf
Behalf为 B2B 买家和卖家提供采购融资服务。作为一家金融机构,维护客户信任至关重要,确保只有符合条件的客户才能访问其 Behalf 账户。
背景
Behalf 基于微服务架构,这意味着每个服务都是松散耦合的,并且具有各自封闭的、定义明确的有界上下文。
从单体架构迁移到微服务架构有很多优势:
- 使用小型组件可以为服务在各个部分中的扩展创造空间。
- 每个微服务都有自己的自主性,并为所使用的技术提供了灵活性。
- 通过允许不同的开发团队同时处理各种组件而不会相互影响,可以提高生产力和速度。
- 开发团队的重点和组织都围绕业务功能。
- 开发人员可以自由地更加独立和自主地工作,而无需依赖其他团队。
然而,作为工程师和架构师,我们在分布式架构中面临着安全挑战。微服务将端点暴露给公众,这些端点通常被称为 API。
- 单体应用只需保护自身安全,这很容易管理。微服务的攻击面更大,这意味着服务数量越多,风险也就越大。每个微服务都需要妥善处理所有可能暴露的漏洞。
- 在单体架构中,组件通过方法调用相互调用。相比之下,微服务可能会公开内部 API(同步调用)来相互通信。这需要投入更多精力和精力来确保其安全。
- 在单体架构中,所有内部组件共享相同的用户会话上下文。而在微服务架构中,组件之间没有任何共享,因此共享用户上下文更加困难,必须在各个微服务之间进行显式处理。
根据上述安全挑战,我们得出结论,微服务的安全性需要与整体安全性以不同的方式解决。
本文将向您介绍在微服务架构中实现灵活、安全和高效的身份验证和授权层所面临的挑战和决策。
身份验证和授权之间的区别
谈到应用程序安全时,这两个术语都会浮现在脑海中。然而,有些人可能会混淆这两个术语的含义。
在身份验证过程中,系统会检查用户的身份,以授予其访问系统的权限。此过程会验证“您是谁? ”,因此用户需要提供登录详细信息进行身份验证。
授权是验证经过身份验证的用户是否有权访问特定信息或执行特定操作的过程。此过程确定用户拥有哪些权限。
微服务架构中的身份验证策略
在从单体架构迁移到微服务架构的过程中,了解如何在微服务领域实现身份验证和授权,对于管理安全性和访问控制至关重要。
有几种方法:
每个服务的身份验证和授权
每个微服务都需要实现独立的安全机制,并在每个入口点强制执行。这种方法赋予微服务团队自主决定如何实施其安全解决方案的权力。然而,这种方法也存在一些缺点:
- 安全逻辑需要在每个微服务中重复实现,这会导致服务之间的代码重复。
- 它分散了开发团队对其领域主要服务的注意力。
- 每个微服务都依赖于用户身份验证数据,但这些数据并不属于它。
- 维护和监控很困难。
- 身份验证应该是一个全球性的解决方案,并作为一个跨领域关注点来处理。
改进此解决方案的一个选项是在每个微服务上加载一个共享的身份验证库。这将避免代码重复,并且开发团队将只专注于其业务领域。然而,这种改进仍然存在一些无法解决的缺点。
全球认证授权服务
在此策略中,专用微服务将处理身份验证和授权问题。每个业务服务必须先对请求进行身份验证,然后将其传递到身份验证服务进行处理。但是,这种方法存在一些缺点:
- 授权检查属于业务问题。特定用户角色在服务上可以执行的操作由业务规则决定。因此,授权问题不应由全局身份验证服务处理。
- 这种策略增加了处理请求的延迟。
每个服务的全局身份验证(API 网关)和授权
在迁移到微服务架构时,需要回答的问题之一是应用程序的客户端如何与微服务通信。一种方法是使用客户端和微服务之间的直接访问。这种方法的弊端是客户端和微服务之间强耦合。
API 网关是所有请求的单一端点入口。它充当使用这些微服务的客户端的中央接口,从而提供灵活性。客户端无需访问多个服务,而是将请求发送到 API 网关,由后者负责将其路由到下游服务。
由于 API 网关是单一端点入口,因此它是强制执行身份验证问题的理想选择。它减少了延迟(调用身份验证服务),并确保了整个应用程序的身份验证过程的一致性。身份验证成功后,安全组件将使用用户/安全上下文(登录用户的身份详细信息)来丰富请求,并将请求路由到强制执行授权检查的下游服务。
身份验证类型:有状态与无状态
在状态身份验证中,服务器在用户成功验证后会为其创建一个会话。会话 ID 随后会以 Cookie 的形式存储在用户浏览器中,并将用户会话存储在缓存或数据库中。当客户端尝试使用给定的会话 ID 访问服务器时,服务器会尝试加载用户会话上下文并将其存储到会话存储中,检查会话是否有效,并决定客户端是否允许访问所需资源或拒绝该请求。
无状态身份验证将用户会话存储在客户端。加密算法对用户会话进行签名,以确保会话数据的完整性和权威性。
每次客户端向服务器请求资源时,服务器都负责验证以 Cookie 形式发送的令牌声明。
由于用户会话存储在客户端,因此这种方法可以释放维护用户会话状态的开销,并且扩展不需要额外的努力。
JSON Web Token(JWT)简介
JWT 是一项开放标准 ( RFC-7519 ),它定义了一种在双方之间安全传输信息的机制。JWT 令牌是一个经过签名的 JSON 对象,其中包含一系列声明,允许接收方验证发送方的身份。
使用 JWT 令牌的目的是为了实现无状态身份验证机制。无状态身份验证将用户会话存储在客户端。
JWT 结构
JSON Web 令牌由三部分组成,以句点分隔。
- 标题包含用于签名的算法。
-
有效负载是会话数据,也引用“声明”。声明有两种类型:
- JWT 规范定义了建议在生成 JWT 令牌时使用的保留声明。
- 定制索赔
-
签名是最关键的部分。签名是通过对标头和有效负载进行 Base64 编码计算得出的。然后,使用标头部分中指定的密钥和加密算法对 encode64 进行签名。签名用于验证令牌未被更改或修改。
JWT 最佳实践和陷阱
- 始终使用 HTTPS 协议来提供更好的保护。这样,客户端浏览器和服务器之间发送的所有数据都会被加密。
- 尽可能减小令牌的大小。JWT 可以是使用 JSON Web 签名 (JWS) 签名的令牌,也可以是使用 JSON Web 加密 (JWE) 提供更高级别的保护的令牌。无论哪种方式,根据经验,令牌都不应包含敏感数据。
- 一些攻击依赖于某些 JWT 库 API 中的歧义性。请通过显式验证算法名称来确保 JWT 库能够抵御此类攻击。
- 确保使用与哈希算法的长度一样长的强密钥。
- 将 JWT 令牌设置为较短的期限,以减少被恶意使用的概率。
- JWT 自动有效,直至过期。如果攻击者获取了令牌,唯一能够“终止”会话的方法是通过状态解决方案明确检测并拒绝这些令牌。
- 使用 JWT 并不能阻止 CSRF 攻击。跨站请求伪造 (CSRF) 是一种网络安全漏洞,它允许攻击者执行他们无法执行的操作。使用同步令牌模式可以阻止此类攻击。
- 有关更多 JWT 最佳实践,请阅读JSON Web Token 当前最佳实践。
结论
身份验证和授权是应用程序的关键核心组件。本文阐述了在微服务架构下构建简洁、健壮的身份验证解决方案时需要考虑的事项。
在下一篇文章中,我们将解释如何实现这一目标。