使用 ALB 身份验证时的安全最佳实践 网络与内容交付
使用 ALB 认证的安全最佳实践
关键要点
AWS 提供内置的 ALB 认证功能,简化用户认证流程。采用共享责任模型,用户需确保安全配置。重要的认证流程与配置细节必须遵循最佳实践,防止未经授权的访问。实施 JWT 验证增强应用程序安全性。在 AWS,安全是我们的首要任务,我们承诺为您提供所需的指导,以增强您环境的安全性。自 2018 年以来,我们推出了 ALB 的内置认证支持,使用户在访问应用程序时能够安全地进行身份验证。此功能使开发人员能够将认证责任从后端目标转移,从而消除了编写复杂认证代码的需求,并简化了应用程序开发流程。为了维护一个强大的安全环境,确保您的应用程序和目标正确配置至关重要。
根据亚马逊网络服务AWS共享责任模型,AWS 负责“云的安全”,涵盖基础设施和服务的安全方面,包括负载均衡软件本身。具体而言,AWS 确保 ALB 所使用的认证机制的安全操作。另一方面,用户负责“云中的安全”,这指的是其配置和使用资源的安全管理。这包括与 ALB 的认证功能相关的参数配置、目标资源的安全组设置,以及在 ALB 后面运行的软件的安全配置。尽管 ALB 处理请求认证,但用户必须确保其应用程序能够安全处理来自 ALB 的请求。
本文将分享最佳实践,帮助您有效使用 ALB 的认证能力,并确保实施强大的安全措施。我们将深入探讨增强环境安全性的最佳实践,通过 ALB 认证共同构建一个更安全和更具韧性的数字生态系统,保护您的数据和应用程序免受潜在威胁。
ALB 认证配置
在配置认证时,您需要为一个或多个监听器规则设置认证操作。authenticatecognito 和 authenticateoidc 操作类型仅支持 HTTPS 监听器,因为非 TLS HTTP 工作负载无法使用认证。以下是监听器默认规则的示例:

json{ Priority default Conditions [] RuleArn arnawselasticloadbalancingltREGIONgtltACCOUNTIDgtlistenerrule/app/alb/AAA/BBB/CCC IsDefault true Actions [ { AuthenticateOidcConfig { OnUnauthenticatedRequest authenticate TokenEndpoint https//ltYOURTOKENENDPOINTgt/ltPATHgt ClientId ltYOURCLIENTIDgt SessionTimeout 604800 AuthorizationEndpoint https//ltYOURAUTHORIZATIONENDPOINTgt/ltPATHgt Scope openid SessionCookieName AWSELBAuthSessionCookie UserInfoEndpoint https//ltYOURUSERINFOENDPOINTgt/ltPATHgt Issuer https//ltYOURISSUERENDPOINTgt/ltPATHgt } Type authenticateoidc Order 1 } { ForwardConfig { TargetGroupStickinessConfig { DurationSeconds 3600 Enabled false } TargetGroups [ { TargetGroupArn arnawselasticloadbalancingltREGIONgtltACCOUNTIDgttargetgroup/TG/DDDD Weight 1 } ] } TargetGroupArn arnawselasticloadbalancingltREGIONgtltACCOUNTIDgttargetgroup/TG/DDDD Type forward Order 2 } ]}
在此示例中,可以看到请求必须在转发到配置的目标组之前完成认证顺序 1。您还可以看到 OnUnauthenticatedRequest 的配置,它接受三个选项:authenticate (默认)、allow 和 deny。
选项解释:
Authenticate: 选项适用于需要用户登录才能显示内容的应用程序。当用户尚未登录时,负载均衡器会将请求重定向到身份提供者IdP的授权端点,并提示用户使用 IdP 的用户界面登录。
Allow: 此选项适用于单页面应用程序SPA。如果需要提供针对不同受众如已认证和未认证用户的多个网页视图,可以使用此选项。例如,如果用户尚未登录且请求不包含声明,则后端可以提供网页的一般视图。如果用户已登录并且请求头中存在声明,则应用程序可以基于这些声明提供个性化的视图。
Deny: 此选项适用于特定页面或路径接收异步请求例如 AJAX,这些请求每几秒重载。在此情况下,对于没有认证信息的请求,负载均衡器将返回 HTTP 401 Unauthorized 错误,而不是将客户端重定向到 IdP 的授权端点。这可以防止未认证的异步请求经历无限重定向。请注意,如果请求包含过期的认证信息,则 ALB 会将客户端重定向到 IdP 的授权端点。
总之,认证选项适用于需要用户认证访问内容的应用,允许选项适用于需要基于认证状态提供不同视图的 SPA,而拒绝选项则适用于处理如果用户未提前认证则不应服务的异步请求。
ALB 认证流程
以下是 ALB 使用 OpenID Connect (OIDC) 验证用户的步骤:
客户端向启用认证的 ALB 后的工作负载发送 HTTPS 请求。ALB 检查请求头中的会话 Cookie,如果未发现会话 Cookie,则重定向用户到 IdP 授权端点,以便 IdP 对用户进行身份验证。用户认证成功后,IdP 将用户重定向回 ALB 并附带一个授权授权代码。负载均衡器向 IdP 令牌端点提交授权授权代码。IdP 将 ID 令牌和访问令牌提供给 ALB。ALB 将访问令牌发送至用户信息端点。用户信息端点使用访问令牌交换用户声明。ALB 重定向到原始统一资源标识符 (URI),并附带 AWSELBAuthSessionCookie,用户使用 AWSELBAuthSessionCookie 请求新的 URI。ALB 验证 Cookie,并将用户信息通过设置 XAMZNOIDC HTTP 头部转发至目标。目标接受请求,验证身份验证信息,然后将响应发送回 ALB。ALB 将最终响应转发给客户端。所有未经身份验证的请求都经历步骤 1 到 11,而经过身份验证的请求则仅需经历步骤 9 到 11,前提是身份验证信息未过期。换句话说,在完成身份验证后,提供正确身份验证信息的用户的请求将被转发至目标组的 ForwardConfig 规则中的配置目标。
实施最佳实践以保护您的目标应用程序
在认证流程的第 10 步中,后端目标接收来自 ALB 的请求并对此类请求提供响应。虽然 ALB 只向配置的目标发送请求,但如果配置允许,目标也可能会接收来自其他源的请求。
为了确保应用程序的安全,有必要通过遵循以下推荐步骤来降低未经授权访问的风险:
限制 ALB 目标仅接收来自可信源的流量:配置目标的安全组仅接受来自 ALB 的流量。这可以通过在目标安全组的入站规则中引用 ALB 的安全组来实现。通过这样的方式,您有效地限制对目标的访问,确保只有 ALB 能够发起与目标的连接。在没有公网 IP 地址或弹性 IP 地址的私有子网中部署 ALB 目标,这样可以防止来自公共互联网的直接访问。
实施 签名验证 用于 ALB 请求中提供的 JSON Web Token (JWT),并确认 JWT 头中的 signer 字段与您的 ALB 的 Amazon 资源名称 (ARN) 匹配。
这些措施有助于防止未经授权的访问并维护应用程序的总体安全性。
第一个建议实际上是任何 ALB 目标的最佳实践。它确保您的目标无法被外部代理访问,从而可能绕过 ALB 资源并危害应用程序的安全性。这样,ALB 完全负责将请求转发至您的目标。
在后续部分中,我们将提供有关如何实施签名验证和签名字段验证的更多细节。
实施 JWT 验证
当负载均衡器成功验证用户时,它会通过 xamznoidcdata HTTP 头将包含身份验证信息的 JWT 发送至目标。JWT 验证对于防止未经授权的访问至关重要。ALB 将 JWT 格式的令牌转发给目标,然而重要的是要注意,这些不是 ID 令牌。相反,ALB 在用户认证过程中创建 新的访问令牌,并仅将 访问令牌 和 用户声明 传递给目标。ALB 使用的 JWT 格式包括头部、有效负载和签名,令牌采用 base64 URL 编码并填充。ALB 使用 ES256ECDSA 使用 P256 和 SHA256生成 JWT 签名。
ALB 认证功能只能与 HTTPS 监听器一起使用,以确保客户端与负载均衡器之间的加密流量。要加密 ALB 与目标之间的认证信息,您必须将目标组配置为使用 HTTPS。在根据 JWT 有效负载中包含的用户声明强制执行您的授权之前,我们强烈建议您的目标应用程序验证有效负载的签名,并验证 signer 字段是否包含预期的 ALB ARN。负载均衡器对用户声明进行签名,使用相应区域的密钥,因此您的应用程序可以验证签名并确保它们是由正确的负载均衡器发送的。
要开始 JWT 令牌的验证,您必须解码 JWT 头部,然后是 JWT 有效负载。解码 JWT 头部时,其内容是包含以下字段的 JSON 对象:
json{ alg algorithm kid 12345678123412341234123456789012 signer arnawselasticloadbalancingregioncodeaccountidloadbalancer/app/ltYOURALBNAMEgt/loadbalancerid iss url client clientid exp expiration}
如您所见,ALB 会在 signer 字段中附加其 ARN,并在创建 JWT 头部时使用与配置的 IdP 连接的 clientid。签名字段使您能够确保头部是由您配置的负载均衡器签名的。
在获取 JWT 头部后,在解码 JWT 有效负载之前,您应验证有效负载的签名。要做到这一点,您需要从 JWT 头部检索密钥 ID (kid) 并使用它查找公开密钥。每个 AWS 区域的端点如下:
https//publickeysauthelbltREGIONgtamazonawscom/keyid
验证签名可确保请求未被篡改。解码 JWT 有效负载后,其内容是包含 IdP 用户信息端点收到的用户声明的 JSON 对象。
json{ sub 12345678123412341234123456789012 email email@exampleorg username myusername exp 1686153020 iss https//ltYOUR ISSUERgt/xxxxxxxxx}
请注意,JWT 签名验证只能在您拥有正确的公共密钥时才能正确完成。此外,为了防止旧签名头的重放,您还应通过检查 JWT 有效负载中的 “exp” 过期字段来验证它。
以下是涉及 JWT 验证的步骤摘要:
目标接收 xamznoidcdata HTTP 头。解码 xamznoidcdata HTTP 头中存在的 base64 编码 JWT 头。验证 “signer” 值,以确保其与为此目标配置的预计 ALB ARN 匹配。从区域端点下载公共密钥,使用 “kid” (密钥 ID) 值。使用下载的公共密钥验证 JWT 有效负载上的签名。验证 JWT 有效负载以确保其尚未过期,通过检查 “exp” 过期字段。有多种编程语言的库用于验证 JWT 签名。我们提供了一个使用 PyJWT 库 的 Python 3x 示例,并在每一步提供注释以帮助您在此基础上进行构建。
Python 3x 使用的签名验证代码示例
pythonimport jwtimport requestsimport base64import json
配置您工作负载运行的区域,如 useast1
region = regioncode
配置预期的 ALB ARN
expectedalbarn = arnawselasticloadbalancingregioncodeaccountidloadbalancer/app/loadbalancername/loadbalancerid
存储来自 xamznoidcdata HTTP 头的编码 JWT
encodedjwt = headersdict[xamznoidcdata]
步骤 1:解码 JWT 头
jwtheaders = encodedjwtsplit()[0]decodedjwtheaders = base64b64decode(jwtheaders)decodedjwtheaders = decodedjwtheadersdecode(utf8)decodedjson = jsonloads(decodedjwtheaders)receivedalbarn = decodedjson[signer]
魔方加速器每天免费2小时This compares the ARN you configured in expectedalbarn with the receivedalbarn
assert expectedalbarn == receivedalbarn Invalid Signer
If the ARN is not the expected one it tells Invalid Signer
步骤 2:从解码 JSON 中提取密钥 ID (kid 字段)
kid = decodedjson[kid]
步骤 3:从区域端点检索公共密钥
url = https//publickeysauthelb region amazonawscom/ kidreq = requestsget(url)pubkey = reqtext
步骤 4:通过验证签名解码编码的 JWT 有效负载
payload = jwtdecode(encodedjwt pubkey algorithms=[ES256])
If the signature is invalid it should return an error such as
Cannot decode JWT token Signature verification failed
其他资源
AWS 提供了一整套资源,以帮助您保护云环境并遵循安全最佳实践。请查看以下附加资源以获取更多信息:
ALB 认证文档:详细介绍如何为部署在 ALB 后的应用配置用户认证。AWS WellArchitected:帮助用户构建优化的 AWS 云应用的框架,其中安全是框架覆盖的支柱之一。它还提供评估工作负载当前状态的工具。AWS Trusted Advisor: 提供与良好架构框架对齐的环境自动检查。AWS Security Hub: 是一项 AWS 服务,具有与 AWS Config 集成的自动安全最佳实践检查。其中一些检查直接与本文主题相关:安全组仅应允许对授权端口的不受限制的传入流量安全组不应允许高风险端口的不受限制访问Elastic Load Balancing (ELB) 最佳实践指南: 关注安全和可靠性的 ALB 使用最佳实践的策划清单。它提到以与本文所述内容一致的方式覆盖目标安全组。结论
总之,使用 ALB 认证功能时保护目标应用程序对于维护其完整性和安全性至关重要。通过实施推荐的安全措施,如将目标访问限制仅限于 ALB,并验证 JWT 签名和签名字段,您可以显著降低未经授权访问的风险。JWT 验证过程确保目标应用程序收到的用户声明是真实的并且来自配置的 ALB。此外,验证 JWT 头中的签名字段确认这些声明是由预期的 ALB 签名的,提供了额外的安全层。遵循这些最佳实践,您可以