AWS Outbound Identity Federation能力介绍

简介: 本文详解AWS 2025年推出的Outbound Identity Federation新能力:让AWS工作负载通过STS签发标准JWT,实现跨云(如对接Azure Entra ID)无密钥身份联合,解决长期凭据管理难题。

阅读前提: 本文假设你对 OAuth 2.0 Client Credentials Flow、JWT 和 OIDC Discovery 有基本了解。如果你对这些概念不太熟悉,建议先阅读附录中的「背景知识速查」部分,再回来阅读正文。

第一章:背景介绍

AWS 在 2025 年 11 月份 IAM 推出了一项新的身份联合能力,AWS IAM Outbound Identity Federation。该功能允许运行在 AWS 上的工作负载通过 AWS Security Token Service (STS) 获取短期有效的 JSON Web Token (JWT),并使用该 JWT 直接向外部服务(如其他云平台、SaaS 产品等)进行身份验证,而无需管理和存储长期有效的凭据(如 API Key、密码、服务账号密钥等)。

在该功能推出之前,当 AWS 上运行的工作负载需要访问外部服务(如 Azure、GCP 或第三方 SaaS)时,通常需要在 AWS 侧存储外部服务的 API Key、Client Secret 或服务账号密钥等长期凭据。这些凭据通常被存放在 AWS Secrets Manager、Parameter Store 或环境变量中,带来了巨大的运维与安全负担:凭据可能泄露、遗忘轮转、或被恶意利用。

Outbound Identity Federation 通过让 AWS 工作负载直接获取短期 JWT 来向外部服务证明身份,完全消除了在 AWS 侧存储外部长期凭据的需求。

在进入具体技术之前,我们先看看现实中有哪些场景会遇到"跨云/跨组织边界的身份认证"这个问题。以下每个场景都有一个共同特征:工作负载需要跨越自身平台的边界,去访问另一个平台上的资源或服务。

场景一:跨云 API 调用

你的团队在 AWS Lambda 上运行了一个数据处理服务。这个服务在处理完数据后,需要调用一个部署在 Azure 上的内部风控评估 API,获取风险评分。这个 API 由另一个团队维护,用 Entra ID 做访问控制。

当前做法:在 Entra ID 中为你的服务创建了一个 App Registration,生成了一个 Client Secret,把它存在 AWS Secrets Manager 里。Lambda 每次执行时从 Secrets Manager 取出 Secret,换一个 Azure Access Token,再拿 Token 去调 API。

场景二:跨云数据传输

你的数据管道跑在 AWS 上(Glue ETL 作业或 Lambda),处理完的数据需要写入 Azure Blob Storage 供下游的 Azure 数据分析团队使用。或者反过来,你需要从 Azure Data Lake 定期拉取数据到 S3。

当前做法:在 Azure 侧创建一个 Storage Account 的 SAS Token 或连接字符串,把它存在 AWS 的环境变量或 Secrets Manager 里。ETL 作业每次运行时用这个凭据完成数据写入或读取。

场景三:并购后的多云整合

公司收购了另一家公司。你们的服务跑在 AWS 上,对方的服务跑在 Azure 上。业务整合要求两边的系统能互相调用,但两套身份体系完全独立。

当前做法:在 Azure 侧为你们的每个 AWS 服务创建 Service Principal,生成 Secret;在 AWS 侧存储这些 Secret。每个对接点都是一对手动管理的凭据。

场景四:SaaS 集成

你的 AWS 服务需要定期将数据写入 Snowflake 做分析,调用 GitHub API 触发 CI/CD 流水线,或者同步数据到 Salesforce。每个 SaaS 集成点都有自己的 API Key 或 OAuth Client Secret。

当前做法:所有这些凭据分散在 Secrets Manager、Parameter Store、甚至环境变量中。运维团队需要记住每个凭据的轮转周期和轮转方式。

场景五:合规驱动的密钥清零

安全团队做了一次 SOC 2 审计,报告中列出了几十个长期凭据作为 finding。安全策略要求:所有跨服务的 M2M 认证必须在 Q2 结束前迁移到无密钥方案。

这些场景的共同痛点

需要注意的是,在单一云平台内部,这个问题其实已经被解决了。AWS 工作负载访问 AWS 资源时,通过 IAM Role 即可完成认证,不需要任何密钥;Azure 工作负载访问 Azure 资源时,通过 Managed Identity 也能做到无密钥认证。云厂商在自己的体系内部都有成熟的身份机制。

真正的痛点出现在"跨边界"的时候——当一个 AWS 工作负载需要访问 Azure 的资源,或者反过来,两套身份体系彼此不认识。传统做法是在调用方存储一个目标平台的长期凭据(Client Secret、API Key、SAS Token 等),用这个凭据来"跨过"边界。这个凭据就成了系统中最脆弱的环节:它可能泄露、可能忘记轮转、可能被写进日志。每多一个跨边界的对接点,就多一个需要手动管理的密钥。

先厘清一件事:两个平台的能力起点完全不同

在深入技术方案之前,有一个关键背景需要先建立——Entra ID 和 AWS 在身份联合方面的能力起点是完全不同的,理解这一点决定了你对本文后续内容的正确预期。

Microsoft Entra ID 是一个全栈身份平台,它的能力覆盖身份联合的所有方向和所有环节。Entra ID 本身就是一个完整的 OIDC Identity Provider,这意味着:Azure 工作负载天然可以拿到一个遵循 OIDC 标准的 JWT,任何支持 OIDC 的外部平台都能验证这个 JWT。此外,Entra ID 还可以通过 Federated Identity Credential 接收和验证来自外部平台的身份,通过 App Registration 定义受保护的 API 和权限模型,通过 App Roles 和 Admin Consent 管理细粒度授权。简单来说,无论是"身份输出"(让 Azure 工作负载的身份被外部验证)还是"身份输入"(验证来自外部的身份),Entra ID 都已经具备完整的能力链,而且这些能力早就存在,不是新功能。

具体而言,如果场景反过来——Azure 工作负载需要调用 AWS 上的某个服务——整个流程不需要任何新功能:

image.svg

这个流程从 Entra ID 诞生之初就能工作——Azure 工作负载拿 Entra ID 签发的 JWT,通过 AWS 的 AssumeRoleWithWebIdentity API 换取 AWS 临时凭证,然后访问 AWS 资源。全程无密钥,全程短期令牌。AWS 在"接收外部身份"方向上的能力(入站联合)一直很完善;Entra ID 在"输出身份"方向上的能力也一直很完善。两边在各自擅长的方向上早就打通了。

真正缺失的环节是:AWS 工作负载的身份"走不出去"。 在 2025 年之前,AWS 的 IAM Role 只能在 AWS 内部使用,无法被外部平台验证。这意味着当 AWS 工作负载需要调用 Azure 或其他外部平台的服务时,唯一的选择是在 AWS 侧存储一个目标平台的长期凭据。2025 年 AWS 推出 Outbound Identity Federation,补上了这个方向的缺口——让 AWS STS 也能像 Entra ID 一样签发 OIDC 标准的 JWT,使 AWS 工作负载的身份可以被外部验证。

这就是本文的聚焦点和阅读预期: 本文主要介绍的是 AWS 这个新增的"身份输出"能力,以及它如何与 Entra ID 的身份平台能力对接。如果你的场景是 Azure → AWS 方向,Entra ID 的现有能力足矣,不需要本文介绍的 AWS Outbound Identity Federation。

下面这张图对比了传统方案和身份联合方案的区别:

image.svg

核心问题来了:当工作负载需要跨越云平台或组织边界时,能不能让两套身份体系直接建立信任,而不依赖共享密钥?

答案是可以的。这就是"身份联合"(Identity Federation)要解决的事。如上所述,Azure → AWS 方向的身份联合早已可行(Entra ID 签发 JWT → AWS AssumeRoleWithWebIdentity),而 2025 年 AWS Outbound Identity Federation 的推出,补上了 AWS → Azure 方向的最后一块拼图。

接下来我们用上面的场景一(AWS Lambda 调用 Azure API)作为主线,完整拆解 AWS → Azure 这个方向的技术实现——因为这是新增能力所在的方向,也是大多数读者最需要了解的方向。

第二章:拆解——跨云身份联合要解决哪两个问题

在动手之前,我们先在概念层面想清楚:当两套不同的身份体系需要建立信任时,到底要解决什么问题?

上一章已经建立了关键背景:Azure → AWS 方向的联合早已打通,本文聚焦的是 AWS → Azure 方向——2025 年才新增可能性的方向,也是实际工程中需要新学习和配置的部分。

在单一云平台内部,身份认证是"透明"的——AWS 工作负载天然拥有 IAM Role,Azure 工作负载天然拥有 Managed Identity,平台自己认识自己签发的身份。但跨云场景下,AWS 的 IAM Role 对 Entra ID 来说只是一串无意义的字符串,反之亦然。要在 AWS → Azure 方向实现身份联合,需要解决两个前后衔接的子问题——而第一章已经展示过,这两个子问题的解决能力在两个平台上是不对称的:Entra ID 覆盖全部环节,AWS 则需要通过 Outbound Identity Federation 来补全"身份输出"这一环。

问题一:身份签发——让调用方的身份"走出"自己的平台

在 AWS 内部,IAM Role 就是工作负载的身份,AWS 服务天然认识它。但当工作负载需要跨出 AWS 的边界去访问 Azure 资源时,问题来了——Entra ID 不认识 IAM Role。调用方需要一种方式,把自己在 AWS 中的身份"翻译"成一个对方能理解和验证的格式。

在传统方案中,这个"翻译"被简化成了一种粗暴的做法:在对方平台创建一个 Client Secret,把它交给调用方保管。调用方通过出示这个 Secret 来证明身份——"我知道这个 Secret,说明我就是那个被授权的客户端。"这本质上是绕过了身份联合,用一个共享密钥来"假装"跨越了边界。

身份联合的思路完全不同——让调用方运行的平台为它签发一个标准格式的身份令牌。 具体来说,AWS STS 签发一个经过 AWS 私钥签名的 JWT,这个 JWT 遵循 OIDC 标准,里面写着"这个请求来自 AWS 账户 123456789012 下的 IAM Role my-lambda-role,此声明由 AWS STS 签发,有效期 5 分钟。"因为 JWT 是一个开放标准,任何支持 OIDC 的服务——包括 Entra ID——都可以通过验证签名来确认这个声明是真实的。

这就是"身份签发"要解决的事:让调用方拿到一个由自己所在平台签名的、短期有效的、遵循开放标准的身份令牌,使其身份可以被跨平台验证。

在 AWS 侧,这个能力在 2025 年之前是缺失的——AWS 的 IAM Role 只能在 AWS 内部使用,无法被外部验证。Outbound Identity Federation 的推出正是为了补上这个缺口。而 Entra ID 天然就是 OIDC IdP,Azure 工作负载本来就能拿到可被外部验证的 JWT,不需要额外的"Outbound"功能。

问题二:身份验证与授权——让被调用方"认识"外部平台的身份

调用方拿到了身份令牌,但被调用方还需要做两件事:

第一,验证身份。 这个 JWT 的签名合法吗?它是不是真的由 AWS STS 签发的?它过期了吗?JWT 里声称的 audience 和我匹配吗?换句话说,被调用方需要"学会"识别来自另一个平台的身份证明——这就是 Federated Identity Credential 的作用,它告诉 Entra ID "我信任 AWS STS 签发的、满足特定条件的 JWT"。

第二,授权。 身份确认了,但这个身份能做什么?能读数据还是能写数据?能访问所有接口还是只能访问特定接口?被调用方需要一套机制来定义和控制不同调用方的权限粒度。在 Azure 内部,Managed Identity 访问 Azure 资源的权限走 Azure RBAC;但当调用方来自外部平台时,Entra ID 的 App Roles 机制让你可以为跨云调用方定义同样细粒度的权限。

在跨云场景中,被调用方如果是一个 Azure 上受 Entra ID 保护的 API,那 Entra ID 就同时承担了验证和授权两个职责:它通过 Federated Identity Credential 验证来自 AWS 的 JWT,通过 App Roles 机制定义和分配权限,最终签发一个包含权限声明的 Access Token 给调用方。

这就是"身份验证与授权"要解决的事:被调用方验证来者身份、并根据预定义的规则决定其权限范围。

在我们的主线场景中,这两个职责都由 Entra ID 承担。事实上,Entra ID 的能力远不止"接收和验证外部 JWT"——从定义 API、定义权限、管理授权到签发 Token,它提供了完整的自闭环能力链。这与 AWS Outbound Identity Federation 只聚焦"身份签发"这一个点形成了显著的能力不对称。

两个问题在主线场景中的位置

回到我们的主线场景——AWS Lambda 调用 Azure 风控 API——把两个子问题叠加到完整流程上:

image.svg

整个流程分三步:

  1. Lambda 向 AWS STS 请求一个 JWT(问题一:身份签发)
  2. Lambda 拿 JWT 向 Entra ID 换一个 Azure Access Token(问题二的前半段:身份验证)
  3. Lambda 拿 Access Token 调用风控 API,API 检查 Token 中的权限声明后放行(问题二的后半段:授权)

搞清楚这个拆解后,接下来两章分别深入每个子问题的技术实现。

第三章:AWS Outbound Identity Federation——身份签发

3.1 它做了什么

AWS 于 2025 年 11 月推出了 IAM Outbound Identity Federation。这个功能做的事情可以用一句话概括:让 AWS STS 成为一个 OIDC Identity Provider,能够为运行在 AWS 上的工作负载签发标准的 JWT。

在此之前,AWS 在身份联合中只扮演"接收方"的角色——外部身份(如 Google、GitHub、Entra ID)可以通过 AssumeRoleWithWebIdentity 联合到 AWS,但 AWS 自己的身份不能联合到外部。这是一个显著的能力缺口:Entra ID 和 GCP 都天然具备向外部签发可验证身份令牌的能力,唯独 AWS 工作负载的身份"走不出去"。Outbound Identity Federation 补上了这个缺口,让 AWS 在身份输出方向追平了其他主流云平台。

核心 API 只有一个:sts:GetWebIdentityToken

image.svg

3.2 JWT 的获取方式

任何拥有 IAM Role 的 AWS 工作负载——EC2、Lambda、ECS、EKS——都可以调用这个 API 获取 JWT。

用 AWS CLI 演示:

JWT=$(aws sts get-web-identity-token \
  --audience "api://AzureADTokenExchange" \
  --signing-algorithm RS256 \
  --query "webIdentityToken" \
  --output text)

用 Python SDK(Lambda 中更常见的方式):

import boto3
sts = boto3.client("sts")
response = sts.get_web_identity_token(
    Audience=["api://AzureADTokenExchange"],
    SigningAlgorithm="RS256",
)
jwt_token = response["WebIdentityToken"]

两种方式做的事情完全一样:向 AWS STS 请求一个 JWT,并指定两个必需参数——Audience(这个 JWT 的目标受众,后面验证方会检查 JWT 中的 aud 字段是否匹配)和 SigningAlgorithm(签名算法,RS256 兼容性更广,ES384 安全性和性能更优)。可选参数包括 DurationSeconds(令牌有效期,60-3600 秒,默认 300 秒)和 Tags(自定义标签,会作为额外 Claims 写入 JWT)。

3.3 JWT 里有什么

GetWebIdentityToken 返回的 JWT 解码后,Payload 部分长这样:

{
  "iss": "https://{uuid}.tokens.sts.global.api.aws",
  "sub": "arn:aws:iam::123456789012:role/my-lambda-role",
  "aud": "api://AzureADTokenExchange",
  "exp": 1735690200,
  "iat": 1735689900,
  "jti": "unique-token-id"
}

关键字段的含义:

iss(Issuer)——签发者。这是启用 Outbound Identity Federation 时为你的 AWS 账户生成的唯一 URL,格式为 https://{uuid}.tokens.sts.global.api.aws。每个 AWS 账户的 Issuer URL 不同,用于保证租户隔离。验证方通过这个 URL 找到 OIDC Discovery 端点({issuer}/.well-known/openid-configuration),下载公钥来验证签名。

sub(Subject)——主体,就是这个工作负载绑定的 IAM Role 的 ARN。它告诉验证方"这个 JWT 代表的是 AWS 账户 123456789012 下的 my-lambda-role 这个角色"。

aud(Audience)——受众,就是调用 API 时传入的 --audience 参数值。验证方会检查这个值是否和自己的标识匹配。

exp(Expiration)——过期时间。默认 300 秒(5 分钟),可通过 DurationSeconds 参数调整,范围 60-3600 秒。

此外,JWT 还包含 AWS 特有的上下文声明(嵌套在 https://sts.amazonaws.com/\ 命名空间下),例如 AWS 账户 ID、源区域、Organization ID、主体标签(Principal Tags),以及计算环境上下文(如 EC2 实例信息、Lambda 函数 ARN 等)。如果调用 API 时传入了 Tags 参数,这些标签也会作为自定义 Claims 出现在 JWT 中。

不过,这个 JWT 里没有任何权限相关的声明——没有 scope、没有 roles、没有 permissions。它的作用是证明"这个请求来自某个特定的 IAM Role",并携带足够的上下文信息让接收方做精细的信任决策。至于这个 Role 能做什么,由接收方自己决定。

3.4 IAM Policy 层面的权限控制

虽然 AWS 不管"JWT 能访问什么",但它通过 IAM Policy 严格控制"谁能签发 JWT"和"可以签发给哪些目标"。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:GetWebIdentityToken",
      "Resource": "*",
      "Condition": {
        "ForAllValues:StringEquals": {
          "sts:IdentityTokenAudience": [
            "api://AzureADTokenExchange",
            "https://accounts.google.com"
          ]
        }
      }
    }
  ]
}

这段 Policy 的意思是:允许当前 Role 调用 GetWebIdentityToken,但只允许它请求 audience 包含 api://AzureADTokenExchangehttps://accounts.google.com\ 的 JWT。如果它尝试请求一个未列入白名单的 audience,调用会被拒绝。

除了 sts:IdentityTokenAudience,AWS 还提供了 sts:DurationSeconds(限制令牌最长有效期)和 sts:SigningAlgorithm(限制签名算法)两个条件键,可以进一步细化控制。

这种控制的意义在于:管理员可以精确限定每个 IAM Role 可以向哪些外部服务联合身份,防止工作负载在未经授权的情况下向任意外部服务出示 AWS 身份。

3.5 启用步骤

使用 Outbound Identity Federation 需要两步前置配置:

第一步:在 IAM Account Settings 中启用功能。 该功能默认关闭,需要管理员显式开启。可以通过 AWS 控制台(IAM → Account Settings)、AWS CLI(aws iam enable-outbound-web-identity-federation)或 Terraform(aws_iam_outbound_web_identity_federation 资源,需 provider v6.27.0+)完成。启用后,AWS 会为你的账户生成一个唯一的 Issuer URL(格式为 https://{uuid}.tokens.sts.global.api.aws),后续配置外部服务信任关系时需要用到这个 URL。

第二步:为目标 IAM Role 添加权限。 通过 IAM Policy 授予 sts:GetWebIdentityToken 权限,并用 Condition 限定可请求的 Audience(通过 sts:IdentityTokenAudience 条件键)。Audience 的限制完全在 IAM Policy 层面实现,不存在账户级别的 Audience 允许列表。

两步都完成后,挂载了该 Role 的工作负载就可以调用 API 获取 JWT 了。

3.6 支持的计算服务

因为 GetWebIdentityToken 本质上就是一个 STS API 调用,所以任何能承载 IAM Role 的 AWS 计算服务都可以使用。AWS 官方演示中明确覆盖的包括 EC2(通过 Instance Profile)、Lambda(通过 Execution Role)、ECS(通过 Task Role)、EKS(通过 IRSA 或 Pod Identity)。理论上 CodeBuild、Glue、SageMaker 等服务也可以使用,但建议使用前确认最新文档。

3.7 明确边界

到这里,必须再强调一次 AWS Outbound Identity Federation 的边界——它只负责身份签发

它做的事:给 AWS 工作负载签发一个短期 JWT,证明"这个请求来自某个 IAM Role"。

它不做的事:不定义外部服务的权限模型,不管理 Scope 或 Role,不验证外部 Token,不提供 Resource Server 注册能力。

这种"只做一件事"的设计意味着,AWS Outbound Identity Federation 自身无法构成一个完整的跨云认证方案——它必须和接收方的身份平台(如 Entra ID、GCP WIF)搭配使用。这也是为什么本文需要两章来分别讲解:AWS 一章只能讲"签发",而 Entra ID 一章要覆盖从"验证"到"授权"的全部链路。

JWT 签发完毕,AWS 这边的工作就结束了。接下来的验证和授权,是接收方的事。在我们的主线场景中,接收方就是 Entra ID——一个能力远超"验证 JWT"的全栈身份平台。

第四章:Entra ID 自定义 Resource Server——身份验证与授权

4.0 先看全貌:Entra ID 的身份平台能力

在进入具体配置之前,值得先退一步看看 Entra ID 的全貌。上一章介绍的 AWS Outbound Identity Federation 只做一件事(签发 JWT),而 Entra ID 是一个覆盖身份生命周期全部环节的平台。理解这个差异,有助于你在后续配置中知道"为什么这个能力在 Entra ID 这边,而不在 AWS 那边"。

Entra ID 的核心能力可以按方向分成三组:

身份输出(Outbound)——让 Azure 工作负载的身份被外部验证。 Entra ID 本身就是一个完整的 OIDC Identity Provider。任何 Azure 工作负载——无论是通过 Managed Identity 还是 App Registration——都可以从 Entra ID 获取一个标准的 JWT,这个 JWT 经过 Entra ID 的私钥签名,任何支持 OIDC 的外部服务都可以通过 Entra ID 的 Discovery 端点获取公钥来验证它。这就是为什么 Azure → AWS 方向的身份联合不需要任何新功能——Entra ID 的"身份输出"能力从第一天就存在。

身份输入(Inbound)——验证来自外部平台的身份。 通过 Federated Identity Credential,Entra ID 可以建立与任何 OIDC 兼容平台的信任关系。无论外部身份来自 AWS、GCP、GitHub Actions 还是 Kubernetes,只要签发方暴露了标准的 OIDC Discovery 端点,Entra ID 就能验证它的 JWT。这是本章的核心内容之一。

API 定义与权限治理——为受保护资源构建完整的访问控制体系。 通过 App Registration 的 Application ID URI 定义 API 标识,通过 App Roles 定义权限模型,通过 Admin Consent 管理授权,最终通过 OAuth 2.0 Token 端点签发包含权限声明的 Access Token。这套机制不区分调用方来自 Azure 内部还是外部平台——对 Entra ID 来说,一旦身份通过验证(无论是通过 Client Secret、证书还是 Federated Credential),后续的权限模型和 Token 签发流程完全一致。

image.svg

在本文的主线场景(AWS → Azure)中,我们只用到了 Entra ID 的"身份输入"和"API 定义与权限治理"这两组能力。 但你需要知道它的"身份输出"能力同样完备——这就是为什么反向场景(Azure → AWS)不需要额外的功能来支撑。AWS Outbound Identity Federation 所做的事情,本质上是让 AWS 在"身份输出"方向上追平了 Entra ID 早已具备的能力。

理解了这个全貌,下面进入具体的配置。

4.1 App Registration 的双重角色

在 Entra ID 中,每一个 App Registration(应用注册)都可以同时扮演两个角色

作为 Client(客户端)——它可以请求访问其他 API 的权限,充当调用方。

作为 Resource Server(资源服务器)——它可以暴露自己的 API,定义谁可以用什么权限来调用它,充当被调用方。

同一个 App Registration 可以只扮演其中一个角色,也可以同时扮演两个。这种设计上的灵活性是理解 Entra ID 能力的起点。

在我们的主线场景中,需要创建两个 App Registration:一个代表 Azure 上的风控 API(Resource Server 角色),一个代表 AWS Lambda(Client 角色)。每个 App Registration 创建后,Entra ID 会自动在当前租户中生成一个对应的 Service Principal——你可以把 App Registration 理解为"应用的定义"(它叫什么、有什么权限),而 Service Principal 是"应用在这个租户中的实例"(实际用来认证和授权的对象)。后面你会看到,权限授予(Admin Consent)是授给 Service Principal 的,而不是直接授给 App Registration。

4.2 把你的 API 变成受保护的 Resource Server

当你希望你的 API 受 Entra ID 保护——也就是说,只有持有合法 Token 的调用方才能访问——你需要在 App Registration 中做以下配置。

设置 Application ID URI

你可以把它理解为你的 API 在 OAuth 世界中的"门牌号"——调用方请求 Token 时要告诉 Entra ID "我要访问哪个 API",用的就是这个标识符。它也会出现在最终 Token 的 aud(audience)字段中,API 验证 Token 时通过检查 aud 来确认"这个 Token 确实是为我签发的"。

格式通常是 api://<client-id>,也可以用自定义域名如 https://api.contoso.com/risk-assessment\。在我们的例子中,假设设置为 api://risk-assessment-api

定义 App Roles

这是关键步骤。在 M2M(机器对机器)场景中,Entra ID 使用 App Roles 来定义权限,而不是 Delegated Scopes。原因很直接:Delegated Scopes 是"代表某个用户"的权限委托,但 M2M 场景中没有人类用户,所以需要一种直接授予给应用本身的权限机制,这就是 App Roles。

在 App Registration 的 manifest 中定义 App Roles:

{
  "appRoles": [
    {
      "allowedMemberTypes": ["Application"],
      "displayName": "Read Risk Scores",
      "value": "RiskScore.Read",
      "description": "允许应用读取风险评分"
    },
    {
      "allowedMemberTypes": ["Application"],
      "displayName": "Write Risk Assessments",
      "value": "RiskAssessment.Write",
      "description": "允许应用提交风险评估请求"
    }
  ]
}

allowedMemberTypes 设置为 ["Application"] 表示这个 Role 可以授予给应用(而非用户)。value 字段的值会出现在最终 Token 的 roles Claim 中,你的 API 代码就是用这个值来做权限判断的。

授权客户端应用

定义好 App Roles 后,管理员需要将具体的 Role 授予给调用方的 Service Principal。这通过 Admin Consent 完成——管理员在 Entra ID 控制台中将 RiskScore.Read 这个 Role 授予给代表 AWS Lambda 的那个 App Registration 的 Service Principal。

授权完成后,当调用方请求 Token 时,Entra ID 会把已授权的所有 App Roles 以 roles Claim 的形式写入 Access Token。

4.3 Federated Identity Credential——信任外部 JWT

到这一步,Entra ID 已经知道"Lambda 这个客户端可以读风险评分",但问题是:Lambda 怎么向 Entra ID 证明自己就是那个客户端?

传统做法是给 Lambda 的 App Registration 生成一个 Client Secret,Lambda 每次请求 Token 时出示这个 Secret。但我们要做的是无密钥方案——用 AWS STS 签发的 JWT 来替代 Client Secret。

这就是 Federated Identity Credential 的作用。它是 Entra ID 提供的一种信任配置,告诉 Entra ID:"当你收到一个来自特定外部身份提供方的 JWT,且其中的声明满足特定条件时,就把这个 JWT 当作合法的客户端身份证明。"

配置方式是在代表 Lambda 的 App Registration 上添加一个 Federated Identity Credential:

{
  "name": "trust-aws-lambda-role",
  "issuer": "https://{uuid}.tokens.sts.global.api.aws",
  "subject": "arn:aws:iam::123456789012:role/my-lambda-role",
  "audiences": ["api://AzureADTokenExchange"],
  "description": "信任 AWS IAM Role my-lambda-role 签发的 JWT"
}

注意issuer 的值是你的 AWS 账户启用 Outbound Identity Federation 后获得的唯一 Issuer URL,不是一个通用的固定地址。你可以通过 aws iam get-outbound-web-identity-federation-info 命令查询你的账户 Issuer URL。

这段配置的每个字段都对应 JWT 中的一个 Claim:

issuer 对应 JWT 的 iss——只接受由你的 AWS 账户的 Issuer URL 签发的 JWT。

subject 对应 JWT 的 sub——只接受 subject 为 arn:aws:iam::123456789012:role/my-lambda-role 的 JWT。

audiences 对应 JWT 的 aud——只接受 audience 为 api://AzureADTokenExchange 的 JWT。

三个条件全部匹配,Entra ID 才会信任这个 JWT。换句话说,这是一个非常精确的信任关系:只有从特定 AWS 账户的特定 IAM Role 上签发的、且目标受众正确的 JWT,才能通过验证。

4.4 Token 请求与响应

配置了 Federated Identity Credential 后,调用方的 Token 请求变成了这样:

POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
client_id={lambda-app-registration-client-id}
scope=api://risk-assessment-api/.default
client_assertion={aws-sts-jwt}
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
grant_type=client_credentials

和传统的 Client Credentials 请求相比,变化只有一处:client_secret 被替换成了 client_assertion(AWS JWT)+ client_assertion_type(声明类型)。

scope 中的 .default 是 Entra ID 的约定——在 Client Credentials Flow 中,你不能请求单个 Scope,只能请求 .default,Entra ID 会把所有已通过 Admin Consent 授权的 App Roles 放进 Token。

Entra ID 收到请求后会做以下验证:

  1. 通过 issuer 的 OIDC Discovery 端点获取 AWS 的公钥
  2. 用公钥验证 JWT 签名
  3. 检查 JWT 的 isssubaud 是否与 Federated Identity Credential 的配置匹配
  4. 检查 JWT 是否过期
  5. 全部通过后,签发 Access Token

返回的 Access Token 解码后:

{
  "iss": "https://login.microsoftonline.com/{tenant-id}/v2.0",
  "sub": "{service-principal-object-id}",
  "aud": "api://risk-assessment-api",
  "roles": ["RiskScore.Read"],
  "exp": 1735689600
}

注意 roles 字段——它包含了管理员授权给 Lambda 的 App Role。你的 API 代码验证 Token 时,检查 aud 是否匹配自己,再检查 roles 中是否包含当前请求所需的权限,就完成了授权决策。

4.5 Entra ID 提供的完整能力链

回顾一下 Entra ID 在这个流程中承担的所有职责:

定义 API。 通过 App Registration 的 Application ID URI,在 OAuth 体系中为你的 API 建立唯一标识。

定义权限。 通过 App Roles,为你的 API 定义细粒度的权限模型(谁能读、谁能写、谁能管理)。

管理授权。 通过 Admin Consent,精确控制哪个客户端被授予了哪些权限。

验证外部身份。 通过 Federated Identity Credential,建立与外部身份提供方(AWS、GCP、GitHub 等)的信任关系。

签发 Token。 验证通过后,签发包含权限声明的 Access Token。

支撑 Token 验证。 通过 OIDC Discovery 端点暴露公钥,让你的 API 代码可以验证 Token 签名。

用一张图来呈现这条完整的能力链:

image.svg

这是一套从"定义 API → 定义权限 → 授权客户端 → 验证身份 → 签发 Token → 验证 Token"的完整链路,全部由 Entra ID 一个平台自洽覆盖。

第五章:合体——完整链路实战

现在把第三章和第四章拼起来,回到主线场景:让 AWS Lambda 在不存储任何 Azure 密钥的情况下,调用受 Entra ID 保护的风控 API。

5.1 全流程概览

image.svg

第 ① 步是身份签发(AWS 的职责),第 ② 步是身份验证(Entra ID 的职责),第 ③ 步是授权(API 自身的职责,基于 Entra ID 签发的 Token 中的 roles)。

全程没有任何长期凭据。

5.2 Azure 侧配置

以下配置在 Azure Portal 的 Entra ID → App registrations 中完成。

Step 1:注册 Resource Server(风控 API)

创建一个 App Registration,命名为 risk-assessment-api

在 "Expose an API" 中设置 Application ID URI 为 api://risk-assessment-api

在 "App roles" 中创建一个 Role:

Display Name:          Read Risk Scores
Value:                 RiskScore.Read
Allowed Member Types:  Applications
Description:           允许应用读取风险评分

Step 2:注册 Client(代表 AWS Lambda)

创建另一个 App Registration,命名为 aws-lambda-client

在 "API Permissions" 中添加 risk-assessment-apiRiskScore.Read 权限(类型为 Application),然后由管理员点击 "Grant admin consent"。

Step 3:配置 Federated Identity Credential

aws-lambda-client 的 "Certificates & secrets" → "Federated credentials" 中添加:

Federated credential scenario:  Other issuer
Issuer:                         https://{uuid}.tokens.sts.global.api.aws
Subject identifier:             arn:aws:iam::123456789012:role/my-lambda-role
Audience:                       api://AzureADTokenExchange
Name:                           trust-aws-lambda-role

Issuer 填写你的 AWS 账户启用 Outbound Identity Federation 后获得的唯一 URL,可通过 aws iam get-outbound-web-identity-federation-info 查询。

到这里,Azure 侧的配置完成。Entra ID 已经知道了三件事:风控 API 暴露了一个 RiskScore.Read 权限;aws-lambda-client 被授予了这个权限;来自 AWS 特定 IAM Role 的 JWT 可以被当作 aws-lambda-client 的身份证明。

5.3 AWS 侧配置

Step 1:启用 Outbound Identity Federation

在 IAM → Account Settings 中开启 Outbound Identity Federation。启用后记录你的账户 Issuer URL(上一步 Azure 侧配置需要用到)。

Step 2:配置 IAM Policy

为 Lambda 的 Execution Role my-lambda-role 附加以下 Policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:GetWebIdentityToken",
      "Resource": "*",
      "Condition": {
        "ForAllValues:StringEquals": {
          "sts:IdentityTokenAudience": "api://AzureADTokenExchange"
        }
      }
    }
  ]
}

到这里,AWS 侧的配置完成。Lambda 的 Execution Role 被允许向 api://AzureADTokenExchange 这个 audience 请求 JWT。

注意:这里的 sts:IdentityTokenAudience 使用单字符串值,因为此场景只需对接一个外部服务。如果你需要允许多个 audience(对接多个外部平台),可以改用数组格式——参见 3.4 节的示例。

5.4 Lambda 代码

import boto3
import requests
# ─── 配置 ────────────────────────────────────────────────
TENANT_ID = "your-azure-tenant-id"
AZURE_CLIENT_ID = "your-aws-lambda-client-app-registration-id"
API_BASE_URL = "https://risk-assessment-api.azurewebsites.net"
# ─────────────────────────────────────────────────────────
def handler(event, context):
    # ──────────────────────────────────────────────────────
    # 第 ① 步:身份签发
    # Lambda 向 AWS STS 请求一个 JWT。
    # 这里不需要任何密钥——Lambda 的 Execution Role 就是它的身份,
    # AWS STS 直接为这个 Role 签发 JWT。
    # ──────────────────────────────────────────────────────
    sts = boto3.client("sts")
    response = sts.get_web_identity_token(
        Audience=["api://AzureADTokenExchange"],
        SigningAlgorithm="RS256",
    )
    aws_jwt = response["WebIdentityToken"]
    # ──────────────────────────────────────────────────────
    # 第 ② 步:身份验证 + Token 交换
    # 拿 AWS JWT 向 Entra ID 的 /token 端点换一个 Azure Access Token。
    # client_assertion 就是 AWS JWT,替代了传统的 client_secret。
    # Entra ID 会验证 JWT 签名、检查 issuer/subject/audience 是否
    # 匹配 Federated Identity Credential 的配置。
    # ──────────────────────────────────────────────────────
    token_response = requests.post(
        f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token",
        data={
            "client_id": AZURE_CLIENT_ID,
            "scope": "api://risk-assessment-api/.default",
            "client_assertion": aws_jwt,
            "client_assertion_type": (
                "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
            ),
            "grant_type": "client_credentials",
        },
    )
    token_response.raise_for_status()
    azure_token = token_response.json()["access_token"]
    # ──────────────────────────────────────────────────────
    # 第 ③ 步:授权访问
    # 拿 Azure Access Token 调用风控 API。
    # API 验证 Token 的签名和 aud 字段,然后检查 roles 中是否包含
    # "RiskScore.Read"。如果包含,返回风险评分;否则返回 403。
    # ──────────────────────────────────────────────────────
    api_response = requests.get(
        f"{API_BASE_URL}/api/risk-score",
        headers={"Authorization": f"Bearer {azure_token}"},
        params={"entity_id": event.get("entity_id")},
    )
    api_response.raise_for_status()
    return api_response.json()

整段代码中没有出现任何密钥、密码或 Secret。Lambda 的身份来自 IAM Role,JWT 来自 STS,Access Token 来自 Entra ID,每一步都是短期令牌,自动过期,无需轮转。

5.5 API 侧的 Token 验证(补充)

为了完整性,简要说明风控 API 的代码需要做什么。以 Python(Flask)为例:

from flask import Flask, request, jsonify
from functools import wraps
import jwt
import requests
app = Flask(__name__)
# Entra ID 的 OIDC 元数据端点
OIDC_CONFIG_URL = (
    "https://login.microsoftonline.com/{tenant-id}"
    "/v2.0/.well-known/openid-configuration"
)
EXPECTED_AUDIENCE = "api://risk-assessment-api"
def get_signing_keys():
    """从 Entra ID 的 JWKS 端点获取公钥"""
    config = requests.get(OIDC_CONFIG_URL).json()
    jwks = requests.get(config["jwks_uri"]).json()
    return {
        k["kid"]: jwt.algorithms.RSAAlgorithm.from_jwk(k)
        for k in jwks["keys"]
    }
def require_role(required_role):
    """装饰器:验证 Token 并检查 roles"""
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            auth_header = request.headers.get("Authorization", "")
            if not auth_header.startswith("Bearer "):
                return jsonify({"error": "Missing token"}), 401
            token = auth_header[7:]
            try:
                # 解码并验证 Token 签名、audience、过期时间
                keys = get_signing_keys()
                header = jwt.get_unverified_header(token)
                key = keys[header["kid"]]
                claims = jwt.decode(
                    token, key,
                    algorithms=["RS256"],
                    audience=EXPECTED_AUDIENCE,
                )
            except Exception:
                return jsonify({"error": "Invalid token"}), 401
            # 检查 roles Claim 中是否包含所需权限
            roles = claims.get("roles", [ ])
            if required_role not in roles:
                return jsonify({"error": "Insufficient permissions"}), 403
            return f(*args, **kwargs)
        return wrapper
    return decorator
@app.route("/api/risk-score")
@require_role("RiskScore.Read")
def get_risk_score():
    entity_id = request.args.get("entity_id")
    # ... 业务逻辑 ...
    return jsonify({"entity_id": entity_id, "risk_score": 42})

API 做的事情就是第二章拆解的"问题二"的后半段——验证 Token 签名、检查 audience、检查 roles,然后做出授权决策。

5.6 变体:跨云数据传输(AWS → Azure Blob Storage)

第一章提到的场景二——AWS 上的服务将数据写入 Azure Blob Storage——和主线场景的链路非常相似,但在两个地方有差异。理解这两个差异,你就能把同样的模式套用到更多跨云场景上。

差异一:Token 请求的 scope 不同

主线场景中,Lambda 请求的 scope 是 api://risk-assessment-api/.default——指向你自己定义的 API。但 Azure Blob Storage 是 Azure 平台的原生服务,它有自己的 resource identifier。请求 Token 时,scope 应为:

scope=https://storage.azure.com/.default

差异二:授权方式不同——用 Azure RBAC 替代 App Roles

主线场景中,权限控制走的是 Entra ID 的 App Roles 机制(你在 App Registration 里自定义 Role,管理员 Grant 给客户端)。但 Azure Blob Storage 是 Azure 的原生资源,它的权限控制走的是 Azure RBAC(基于角色的访问控制)。

具体做法是:在 Azure Portal 中,找到目标 Storage Account,在 "Access Control (IAM)" 中将 Storage Blob Data Contributor 这个内置角色分配给 aws-lambda-client 的 Service Principal。这就等同于告诉 Azure:"这个 Service Principal 有权读写这个 Storage Account 里的 Blob 数据。"

Lambda 代码层面的变化

身份签发(第 ① 步)完全不变。Token 交换(第 ② 步)只是 scope 变了。真正的差别在第 ③ 步——调用 Azure Blob Storage SDK 而不是调用自定义 API:

from azure.identity import ClientAssertionCredential
from azure.storage.blob import BlobServiceClient
def get_aws_jwt():
    """获取 AWS STS 签发的 JWT"""
    sts = boto3.client("sts")
    response = sts.get_web_identity_token(
        Audience=["api://AzureADTokenExchange"],
        SigningAlgorithm="RS256",
    )
    return response["WebIdentityToken"]
# 使用 ClientAssertionCredential:它会自动在需要 Token 时
# 调用 get_aws_jwt() 获取最新的 AWS JWT,并用它向 Entra ID 换 Token。
credential = ClientAssertionCredential(
    tenant_id=TENANT_ID,
    client_id=AZURE_CLIENT_ID,
    func=get_aws_jwt,
)
# 用这个 credential 初始化 Blob Storage 客户端
blob_service = BlobServiceClient(
    account_url="https://mystorageaccount.blob.core.windows.net",
    credential=credential,
)
# 写入数据
blob_client = blob_service.get_blob_client(
    container="processed-data", blob="output.parquet"
)
with open("/tmp/output.parquet", "rb") as data:
    blob_client.upload_blob(data, overwrite=True)

Azure SDK 的 ClientAssertionCredential 封装了 Token 交换的全部逻辑——你只需要给它一个返回 JWT 的函数,它会在需要时自动调用这个函数拿 JWT、换 Token、刷新 Token。你的业务代码完全不需要手动处理 Token。

小结:模式是同一个,细节可调整

无论是调用自定义 API 还是写入 Azure Blob Storage,身份签发(AWS STS 签发 JWT)和身份验证(Entra ID 验证 JWT + 签发 Token)这两步是完全一样的。差异只在于被调用方的权限模型——自定义 API 用 App Roles,Azure 原生服务用 Azure RBAC;以及 scope 的值——自定义 API 用你定义的 Application ID URI,Azure 原生服务用 Azure 预定义的 resource identifier。

第六章:决策指南——什么场景用什么

6.1 场景矩阵

场景

推荐方案

说明

AWS 工作负载调用 Azure API

AWS Outbound Identity Federation + Entra ID Federated Credential

本文主线场景。AWS 补全身份输出能力,Entra ID 承接验证和授权。

AWS 工作负载写入 Azure Blob Storage

AWS Outbound Identity Federation + Entra ID + Azure RBAC

与 API 调用类似,但授权走 Azure RBAC(如分配 Storage Blob Data Contributor 角色给 Service Principal),而非 App Roles。

Azure 工作负载调用 AWS 资源

Entra ID(签发 JWT)+ AWS AssumeRoleWithWebIdentity

无需 Outbound Identity Federation。Entra ID 天然是 OIDC IdP,AWS 通过入站联合验证其 JWT。此方向早已可行。(参见第一章流程图)

AWS 工作负载调用 GCP 资源

AWS Outbound Identity Federation + GCP Workload Identity Federation

AWS 签发 JWT,GCP 的 WIF 验证并交换 GCP Access Token。

AWS 工作负载调用 Snowflake

AWS Outbound Identity Federation + Snowflake Workload Identity Federation

Snowflake 原生支持接受 AWS JWT。

Azure 上的 API 需要被多个外部平台调用

Entra ID 自定义 Resource Server(App Roles + Federated Identity Credential)

为每个外部平台分别配置 Federated Identity Credential,通过 App Roles 统一管理权限。

纯 Azure 内部的微服务 M2M 认证

Entra ID App Registration + App Roles + Managed Identity

不涉及 AWS,不需要 Outbound Identity Federation。使用 Managed Identity 替代 Client Secret。

纯 AWS 内部的微服务 M2M 认证

IAM Role + STS AssumeRole

不涉及外部身份联合,使用 AWS 原生的角色链机制。

需要为自建 API 定义细粒度权限模型

Entra ID 自定义 Resource Server

AWS 不提供类似的 Resource Server 注册和权限定义能力。

合规要求消除所有跨云长期凭据

AWS Outbound Identity Federation + 对端的 Federation 能力

对端可以是 Entra ID、GCP WIF、Snowflake WIF 等。

6.2 能力不对称性与平台定位

第一章和第四章已经从不同角度展示了两个平台之间的能力不对称性,这里做一个总结。

核心结论很简单:Entra ID 是一个能力自洽的全栈身份平台,双向(输出 + 输入)和全环节(签发 + 验证 + 授权 + 权限定义)都覆盖;AWS Outbound Identity Federation 是 AWS 在"身份输出"这一个方向上的能力补全。

这种不对称性的最直观证据就是反向场景:Azure 工作负载访问 AWS 资源,只需要 Entra ID 的原生 JWT 签发能力 + AWS 的 AssumeRoleWithWebIdentity,整个流程不涉及任何新功能(详见第一章的流程图)。而 AWS → Azure 方向在 2025 年之前是做不到无密钥的——必须等 Outbound Identity Federation 推出才补上了 AWS 侧的签发环节。

设计跨云架构时的实际含义:

Entra ID 可以独立支撑完整的身份治理方案——无论是定义 API、管理权限、接收外部身份,还是向外输出身份,它都不需要依赖其他平台的能力。

AWS Outbound Identity Federation 必须与接收方的身份平台搭配才能构成可工作的方案——它只签发 JWT,验证、授权、权限模型全部交给对端(Entra ID、GCP WIF、Snowflake WIF 等)。

在"AWS → Azure"方向上,两者确实各有分工,但这不是两个对等工具之间的"互补",而是一个专项能力补全(AWS Outbound)和一个完整平台(Entra ID)之间的配合。

6.3 能力对照速查

能力维度

AWS Outbound Identity Federation

Microsoft Entra ID

签发 JWT 给外部

支持(GetWebIdentityToken,2025 年新增)

原生支持(Entra ID 本身就是 OIDC IdP,一直具备)

接受外部 JWT

不适用于此功能(入站联合由 AssumeRoleWithWebIdentity 处理)

支持(Federated Identity Credential)

自定义 Resource Server

不支持

完整支持(App Registration + Application ID URI)

定义权限模型

不适用

支持(App Roles / Delegated Scopes)

M2M 权限控制

IAM Policy Condition(控制签发范围)

App Roles + Admin Consent(控制访问范围)

Token 中的权限声明

无权限声明(JWT 含身份 + AWS 上下文信息,但不含 scope/roles)

有(roles Claim)

能否独立支撑跨云方案

否,必须与接收方身份平台搭配

是,身份输出 + 输入 + 权限治理全覆盖

反向场景是否需要额外能力

不适用(AWS 作为接收方时走 AssumeRoleWithWebIdentity)

不需要,Entra ID 现有能力即可完成 Azure → AWS 身份联合

审计

CloudTrail 记录 GetWebIdentityToken 调用

Entra ID Sign-in Logs / Audit Logs

附录

背景知识速查

如果你对 OAuth 2.0 Client Credentials Flow、JWT 或 OIDC Discovery 不太熟悉,这一节帮你快速建立必要的背景知识。已经了解这些概念的读者可以跳过。

Client Credentials Flow

OAuth 2.0 定义了多种授权流程,Client Credentials Flow 是其中最简单的一种,专门用于"机器对机器"(M2M)场景——没有人类用户参与,纯粹是一个服务调用另一个服务。

流程只有一步交互:客户端(调用方服务)向授权服务器出示自己的 client_id 和凭据(通常是 client_secret),授权服务器验证通过后返回一个 Access Token。客户端拿着这个 Token 去调用目标 API,目标 API 验证 Token 的合法性后决定是否放行。

image.svg

整个流程的安全性取决于一件事:客户端的凭据有多安全。 传统做法是用 client_secret(一个静态字符串),这正是本文要解决的问题。

参考:RFC 6749 Section 4.4 - Client Credentials Grant

JWT(JSON Web Token)

JWT 是一种经过数字签名的 JSON 数据结构,格式是三段 Base64 编码用点号连接:header.payload.signature

一个典型的 JWT Payload 长这样(以 OIDC 标准格式为例):

{
  "iss": "https://idp.example.com",
  "sub": "service-account-001",
  "aud": "https://api.example.com",
  "exp": 1735690200
}

四个关键字段:iss(issuer,谁签发的)、sub(subject,代表谁)、aud(audience,给谁用的)、exp(expiration,什么时候过期)。

JWT 的核心价值在于:收到 JWT 的一方可以通过验证签名来确认这个 Token 确实是由声称的签发方签发的,没有被篡改。 验证签名需要签发方的公钥。

OIDC Discovery

那验证方怎么拿到签发方的公钥?OIDC(OpenID Connect)定义了一套标准化的发现机制:任何 OIDC 兼容的身份提供方都会在一个固定路径 /.well-known/openid-configuration 上发布自己的元数据,其中包含公钥端点(jwks_uri)的地址。

OpenID Connect Discovery 规范 中的示例为例,假设签发方的 Issuer 是 https://server.example.com\

image.svg

这是一个与具体厂商无关的标准协议。无论签发方是 AWS STS、Entra ID、Google 还是任何其他 OIDC 兼容的服务,只要它暴露了标准的 Discovery 端点,任何遵循标准的验证方都能自动完成公钥获取和签名验证,不需要双方提前交换密钥。这种"基于标准协议的自动信任建立"正是正文中跨云身份联合能够工作的基础。

参考:OpenID Connect Discovery 1.0 规范

术语对照表

概念

AWS 术语

Entra ID 术语

身份平台

AWS IAM + STS

Microsoft Entra ID

工作负载身份

IAM Role

App Registration + Service Principal(或 Managed Identity)

保护 API

无对标能力

Expose an API(Application ID URI + App Roles)

M2M 权限

IAM Policy Condition(sts:IdentityTokenAudience

App Roles + Admin Consent

签发身份令牌给外部

Outbound Identity Federation(GetWebIdentityToken,2025 年新增)

Entra ID 本身就是 OIDC IdP(原生能力)

接受外部身份令牌

AssumeRoleWithWebIdentity(入站联合,一直存在)

Federated Identity Credential

权限授予机制

IAM Policy Allow + Condition

Admin Consent

审计日志

CloudTrail

Sign-in Logs / Audit Logs

参考链接

AWS 官方资源:

Microsoft 官方资源:

社区实践:

协议规范:

目录
相关文章
|
存储 缓存 文件存储
如何保证分布式文件系统的数据一致性
分布式文件系统需要向上层应用提供透明的客户端缓存,从而缓解网络延时现象,更好地支持客户端性能水平扩展,同时也降低对文件服务器的访问压力。当考虑客户端缓存的时候,由于在客户端上引入了多个本地数据副本(Replica),就相应地需要提供客户端对数据访问的全局数据一致性。
32704 79
如何保证分布式文件系统的数据一致性
|
前端开发 容器
HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局(上)
HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局
17757 20
|
设计模式 存储 监控
设计模式(C++版)
看懂UML类图和时序图30分钟学会UML类图设计原则单一职责原则定义:单一职责原则,所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。bad case:IPhone类承担了协议管理(Dial、HangUp)、数据传送(Chat)。good case:里式替换原则定义:里氏代换原则(Liskov 
36685 20
设计模式(C++版)
|
存储 编译器 C语言
抽丝剥茧C语言(初阶 下)(下)
抽丝剥茧C语言(初阶 下)
|
机器学习/深度学习 人工智能 自然语言处理
带你简单了解Chatgpt背后的秘密:大语言模型所需要条件(数据算法算力)以及其当前阶段的缺点局限性
带你简单了解Chatgpt背后的秘密:大语言模型所需要条件(数据算法算力)以及其当前阶段的缺点局限性
24765 14
|
机器学习/深度学习 弹性计算 监控
重生之---我测阿里云U1实例(通用算力型)
阿里云产品全线降价的一力作,2023年4月阿里云推出新款通用算力型ECS云服务器Universal实例,该款服务器的真实表现如何?让我先测为敬!
36665 15
重生之---我测阿里云U1实例(通用算力型)
|
SQL 存储 弹性计算
Redis性能高30%,阿里云倚天ECS性能摸底和迁移实践
Redis在倚天ECS环境下与同规格的基于 x86 的 ECS 实例相比,Redis 部署在基于 Yitian 710 的 ECS 上可获得高达 30% 的吞吐量优势。成本方面基于倚天710的G8y实例售价比G7实例低23%,总性价比提高50%;按照相同算法,相对G8a,性价比为1.4倍左右。
|
存储 算法 Java
【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的限流器RateLimiter功能服务
随着互联网的快速发展,越来越多的应用程序需要处理大量的请求。如果没有限制,这些请求可能会导致应用程序崩溃或变得不可用。因此,限流器是一种非常重要的技术,可以帮助应用程序控制请求的数量和速率,以保持稳定和可靠的运行。
29840 52

热门文章

最新文章

下一篇
开通oss服务