开始使用出站身份联合验证 - Amazon Identity and Access Management
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

开始使用出站身份联合验证

本指南向您展示如何为您的 Amazon 账户启用出站身份联合验证以及如何获取您的第一个 JSON Web 令牌(JWT)(使用 GetWebIdentityToken API)。您将启用该功能,与外部服务建立信任关系,配置 IAM 权限,并使用 Amazon CLI 或适用于 Python 的 Amazon SDK(Boto3)请求令牌。

先决条件

在开始之前,请确保您满足以下条件:

  • 已安装最新版本的 Amazon CLI 或 Python 3.8(或更高版本)和 Boto3(适用于 Amazon SDK 示例)

  • 可以在其中配置信任关系的外部服务帐户(例如外部云提供商、SaaS 提供商或测试应用程序)

注意
  • GetWebIdentityToken API 在 STS 全局端点上不可用。

  • GetWebIdentityToken API 生成的 JSON Web 令牌(JWT)不能用于通过 OpenID Connect(OIDC)联合身份验证登录 Amazon(通过 AssumeRoleWithWebIdentity API)。

为您的账户启用出站身份联合验证

必须先启用出站身份联合验证,然后才能请求令牌。您可以使用 Amazon 管理控制台启用该功能,也可以使用 EnableOutboundWebIdentityFederation API 以编程方式启用该功能。

使用 Amazon CLI

aws iam enable-outbound-web-identity-federation

使用适用于 Python 的 Amazon SDK

import boto3 # Create IAM client iam_client = boto3.client('iam') # Enable outbound identity federation response = iam_client.enable_outbound_web_identity_federation() print(f"Feature enabled. Issuer URL: {response['IssuerUrl']}") print(f"Status: {response['Status']}")

使用 Amazon 控制台

导航到 IAM,然后在左侧导航菜单的访问管理部分下选择账户设置

启用该功能后,请记下您的账户特定发布者 URL。在外部服务中配置信任关系时,您将使用此 URL。您也可以根据需要使用 GetOutboundWebIdentityFederationInfo API 检索此发布者 URL。

在外部服务中建立信任关系

将外部服务配置为信任并接受由您的 Amazon 账户发布的令牌。具体步骤因服务而有所不同,但通常包括:

  • 将您的 Amazon 账户发布者 URL 注册为可信身份提供商

  • 配置要验证的声明(受众、主题模式)

  • 将令牌声明映射到外部服务中的权限

有关详细的配置说明,请参阅外部服务文档。

配置 IAM 权限

创建一个 IAM 策略,授予调用 GetWebIdentityToken API 的权限,然后将该策略附加到需要生成令牌的 IAM 角色。

此示例策略授予生成令牌的权限,但具有特定限制。其仅允许为受众“https://api.example.com”请求令牌,并且强制规定最长令牌生命周期为 5 分钟(300 秒)。有关可用于强制执行令牌属性的条件键列表,请参阅 IAM 和 Amazon STS 条件上下文密钥

示例 IAM 策略

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:GetWebIdentityToken", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "sts:IdentityTokenAudience": "https://api.example.com" }, "NumericLessThanEquals": { "sts:DurationSeconds": 300 } } } ] }

请求您的第一个 JSON Web 令牌(JWT)

您可以使用 GetWebIdentityToken API 请求 JSON Web 令牌。调用 API 时可以指定以下参数:

  • 受众(必填):令牌的预期接收者。该值填充 JWT 中的“aud”声明。外部服务验证此声明,以确保令牌是为其准备的。

  • SigningAlgorithm(必填):用于对令牌进行签名的加密算法。有效值为 ES384 和 RS256。使用 ES384 可获得最佳安全性和性能,或使用 RS256 可实现与不支持 ECDSA 的系统更广泛的兼容性。

  • DurationSeconds(可选):令牌生命周期(以秒为单位)。有效值范围为 60 至 3600。默认值为 300(5 分钟)。我们建议缩短令牌生命周期以提高安全性。

  • 标签(可选):要作为自定义声明包含在令牌中的键值对列表。外部服务可以使用这些声明进行精细授权。

该 API 会返回以下字段:

  • IdentityToken:已签名的 JWT,以 base64url 编码字符串的形式表示。将此令牌包含在对外部服务的请求中。

  • 过期:令牌过期时的 UTC 时间戳。

使用 Amazon CLI

aws sts get-web-identity-token \ --audience "https://api.example.com" \ --signing-algorithm ES384 \ --duration-seconds 300 \ --tags Key=team,Value=data-engineering \ Key=environment,Value=production \ Key=cost-center,Value=analytics

使用适用于 Python 的 Amazon SDK

import boto3 sts_client = boto3.client('sts') response = sts_client.get_web_identity_token( Audience=['https://api.example.com'], DurationSeconds=300, SigningAlgorithm='RS256', Tags=[ {'Key': 'team', 'Value': 'data-engineering'}, {'Key': 'environment', 'Value': 'production'}, {'Key': 'cost-center', 'Value': 'analytics'} ] ) token = response['WebIdentityToken']

您也可以使用标准 JWT 库(例如 PyJWT、Python-jose for Python、Nimbus JOSE+JWT for Java 或 jwt.io 之类的调试程序)解码 JWT 以检查其内容。有关令牌中包含的声明的更多信息,请参阅了解令牌声明

将令牌与外部服务一起使用

收到令牌后,将其包含在对外部服务的请求中。方法因服务而有所不同,但大多数服务都接受 Authorization 标头中的令牌。外部服务应实现令牌验证逻辑,以在授予对 Amazon 工作负载的访问权限之前,从发布者的知名端点获取 JWKS 密钥,验证令牌的签名并验证基本声明。

从 OpenID Connect(OIDC)端点获取验证密钥和元数据

您 Amazon 账户唯一的发布者 URL 可托管 OpenID Connect(OIDC)发现端点,其中包含令牌验证所需的验证密钥和元数据。

OIDC 发现端点 URL 包含一些提供商用于验证令牌的元数据。网址为:

{issuer_url}/.well-known/openid-configuration

JWKS(JSON Web 密钥集)端点包含用于验证令牌签名的密钥。网址为:

{issuer_url}/.well-known/jwks.json

使用 curl 获取 JWKS

curl https://{issuer_url}/.well-known/jwks.json

响应:

{ "keys": [ { "kty": "EC", "use": "sig", "kid": "key-id-1", "alg": "ES384", "crv": "P-384", "x": "base64-encoded-x-coordinate", "y": "base64-encoded-y-coordinate" }, { "kty": "RSA", "use": "sig", "kid": "key-id-2", "n": "base64-encoded-modulus", "e": "AQAB" } ] }

使用适用于 Python 的 Amazon SDK

import requests # Fetch Openid Configuration open_id_config_response = requests.get("https://{issuer_url}/.well-known/openid-configuration") open_id_config = open_id_config_response.json() # Fetch JWKS jwks_response = requests.get("https://{issuer_url}/.well-known/jwks.json") jwks = jwks_response.json()

我们建议缓存这些密钥,以避免每次验证令牌时都需要重新获取。

基本声明验证

  • 主题(sub):验证主题声明是否包含预期的 IAM 主体 ARN 模式。

  • 过期(exp):确保令牌未过期。JWT 库通常会自动处理此问题。

  • 受众(aud):验证受众是否匹配您的预期值。这样可以防止原本用于其他服务的令牌与您的令牌混用。

  • 发布者(iss):验证发布者是否匹配您信任的 Amazon 账户。维护可信发布者 URL 列表。

应尽可能验证其他 Amazon 特定声明,以在外部服务中实现精细访问控制。例如,验证 org_id 声明以限制 Amazon Organization 中 IAM 主体的访问权限,选中 principal_tags 以强制执行基于属性的访问控制(例如仅允许生产环境或特定团队),或者验证 lambda_source_function_arn 或 ec2_instance_source_vpc 等会话上下文声明以根据计算资源限制访问权限。有关令牌中所包含声明的完整列表,请参阅了解令牌声明