本指南介绍如何使用 Microsoft Entra ID 身份验证 SDK(sidecar)向下游 API 进行身份验证来保护 Amazon Bedrock 代理。 边车作为独立容器运行,处理所有凭据管理和与 Microsoft Entra ID 的令牌交换。 代理从 sidecar 请求授权标头,sidecar 处理与 Microsoft Entra ID 的 OAuth 2.0 交换。
先决条件
在开始之前,请确保具备:
- Microsoft Entra 的租户。
- 一份 Azure 订阅。
- Docker Desktop(macOS/Windows)或包含 Compose v2(Linux)的 Docker 引擎。
- PowerShell 7+。
- Azure CLI。
- AWS CLI v2。
- 已启用 Anthropic Claude 3 Haiku(或你首选的模型)Bedrock 模型访问权限的 AWS 帐户。 在“模型访问>”下的 AWS Bedrock 控制台中启用访问权限。
- 首次 Microsoft Entra 设置的全局管理员角色。 使用 Privileged Identity Management (PIM)实时激活此角色。
克隆示例存储库
克隆存储库并转到 AWS 示例目录:
git clone https://github.com/microsoft/entra-agentid-samples.git cd entra-agentid-samples/sidecar/aws
Architecture
Microsoft Entra ID身份验证 SDK(sidecar)位于代理和Microsoft Entra ID之间。 代理从不直接与Microsoft Entra ID对话,也从不管理凭据。 它请求 sidecar 提供 Authorization 标头,以调用下游 API。 Amazon Bedrock 单独处理 LLM 推理,无需担心标识。
此示例在 Docker 网桥网络上运行三个容器:
-
llm-agent-aws: 具有聊天 UI 和 LangGraph ReAct 代理的 Flask 应用,该代理调用 Amazon Bedrock (Claude) 进行推理。 在端口 3001 上开放。 -
agent-id-sidecar-aws:Microsoft Entra ID 官方身份验证 SDK(sidecar)容器。 获取和缓存令牌。 没有主机端口,只能从 Docker 网络内部访问。 -
weather-api-aws: 一个下游 API,用于验证代理的每个请求的 JWT(签名、颁发者、到期、访问群体),并返回天气数据。
请求将流经以下步骤:
- 在聊天 UI
http://localhost:3001中键入查询。 - Flask 应用通过 LangGraph ReAct 代理将查询发送到 AWS Bedrock (Claude)。
- 当 Claude 确定它需要天气数据时,它会调用该工具
get_weather。 - 该工具通过调用
GET /AuthorizationHeader?AgentIdentity={agentId}向 sidecar 请求授权标头。 - sidecar 使用 OAuth 2.0(客户端凭据或 OBO(代表用户)交换)向 Microsoft Entra ID 进行身份验证。
- Microsoft Entra ID 将请求的令牌 (TR) 返回至 sidecar。
- 智能体使用
Authorization: Bearer TR调用天气 API。 - 天气 API 验证 TR 并返回天气 JSON 响应。
了解令牌流动
标识交换涉及三个令牌:
| 令牌 | 颁发给 | 何时 | 方式 |
|---|---|---|---|
| Tc | 已登录用户 | 仅限 OBO 流 | 浏览器中的 MSAL.js |
| T1 | 蓝图应用 | 这两个流 | Sidecar (客户端凭据) |
| TR | 代理(下游 API) | 这两个流 | 边车仅应用(自治)或 OBO 交换 |
在自治流中,边车使用客户端凭据获取 T1,然后将其交换为范围为下游 API 的 TR。 在 OBO 流中,sidecar 还会接收 Tc(用户的令牌),并执行 OBO 交换来获取代表已登录用户的 TR。
在此设置中,仅向主机公开聊天 UI(端口 3001)。 Sidecar 和天气 API 只能在 Docker 网络中访问,该网络可建立明确的安全边界。
选择执行模式和标识流
此示例支持两种执行模式和两个可以组合的标识流:
| 自治 (仅限应用) | OBO (代表用户) | |
|---|---|---|
| 直接 (无 LLM) | 快速演示路径。 获取令牌并调用天气 API。 | 同样,但使用经过身份验证的 sidecar 终结点和用户令牌。 |
| Bedrock + LangChain | LangGraph ReAct 代理决定何时调用 get_weather。 |
同样,但代理在工具运行时传递用户令牌。 |
使用直接模式来进行令牌流的端到端验证,无需访问 AWS Bedrock。 切换到 Bedrock 模式以获取完整的代理体验。
选择 AWS 身份验证层
此示例支持通过三种方法向 Amazon Bedrock 进行身份验证。 选择与您的系统环境匹配的级别:
-
临时 STS 凭据: 最适合使用 AWS SSO 进行本地开发。 在您的
AWS_ACCESS_KEY_ID文件中设置AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN和.env。 这些凭据在大约一小时后过期。 -
基岩 API 密钥: 最适合演示和研讨会。 在
AWS_BEARER_TOKEN_BEDROCK文件中设置.env。 仅适用于贝德洛克,并具有可配置的生命周期。 -
OIDC 联合身份验证:最适合Azure 应用服务的生产部署。 使用平台设置的
AWS_ROLE_ARN和AWS_WEB_IDENTITY_TOKEN_FILE。 没有机密存储在任何地方。
选择基岩模型
该示例默认为 us.anthropic.claude-3-haiku-20240307-v1:0,因为它是 Bedrock 上最便宜的Anthropic模型,并支持工具调用。 前缀 us. 指示跨区域推理配置文件,该配置文件在美国区域之间路由以实现更高的可用性。
其他受支持的模型:
| 模型标识符 | 每 1K 个输入令牌的成本 | 备注 |
|---|---|---|
us.anthropic.claude-3-haiku-20240307-v1:0 |
$0.00025 | 违约。 快速、最便宜,并支持工具调用。 |
us.anthropic.claude-3-5-haiku-20241022-v1:0 |
$0.0008 | 更新,更智能,仍然负担得起。 |
us.anthropic.claude-3-5-sonnet-20241022-v2:0 |
$0.003 | 最佳质量/成本比率。 |
通过在BEDROCK_MODEL_ID文件中设置.env来覆盖默认设置。 必须先在 AWS Bedrock 控制台>模型访问 中启用每个模型,然后才能调用该模型。
创建Microsoft Entra对象(首次设置)
如果你已有上一次运行中 .env 已填充的 BLUEPRINT_APP_ID 文件,请跳转到配置环境变量。
为每个租户运行以下命令一次,以创建用于 OBO 登录的蓝图应用、代理 ID 和 SPA 应用。
按照 创建代理身份蓝图 和 创建代理身份 中的 PowerShell 工作流,为自动化流程创建蓝图应用和代理 ID。 最后,你有:
-
TENANT_ID:Microsoft Entra 租户。 -
BLUEPRINT_APP_ID: 蓝图应用注册。 -
BLUEPRINT_CLIENT_SECRET: 蓝图的客户端密钥。 -
AGENT_CLIENT_ID: 从蓝图创建的代理 ID。
-
(可选)创建 SPA 应用并配置 OBO。 仅当想要使用 OBO 标识流时,才需要执行此步骤:
运行以下脚本以创建 SPA 应用注册并在蓝图上配置 OBO 权限。 脚本注册 SPA 重定向 URI 并授予所需的委派权限。
Bash:
bash ../../scripts/setup-obo-client-app.sh bash ../../scripts/setup-obo-blueprint.shPowerShell:
pwsh ../../scripts/setup-obo-client-app.ps1 pwsh ../../scripts/setup-obo-blueprint.ps1 ` -TenantId '<TENANT_ID>' ` -BlueprintAppId '<BLUEPRINT_APP_ID>' ` -AgentAppId '<AGENT_CLIENT_ID>' ` -ClientSpaAppId '<CLIENT_SPA_APP_ID>'
此示例的 SPA 重定向 URI 为 http://localhost:3001 (端口 3001,而不是 3003)。 请确保已注册此 URI。
配置环境变量
通过 AzureAd__ClientCredentials__0__SourceType 中的 docker-compose.yml 设置,Sidecar 支持多种凭据类型:
-
ClientSecret: 仅限本地开发。 此示例包含此类型。 -
SignedAssertionFromManagedIdentity:部署在Azure上。 建议采用零秘密原则进行生产。 -
KeyVault:来自Azure 密钥保管库的证书。 -
StoreWithThumbprint: 来自本地计算机存储的证书。
- 从包含的模板创建本地
.env配置文件。 此文件存储租户、应用和 AWS 凭据:
Bash:
cp .env.example .env
PowerShell:
Copy-Item .env.example .env
在
.env文件中设置以下变量:-
TENANT_ID: 你的 Microsoft Entra 租户 ID。 -
BLUEPRINT_APP_ID: 蓝图应用注册。 sidecar 作为此应用进行身份验证。 -
BLUEPRINT_CLIENT_SECRET: 蓝图客户端密码(仅限本地开发)。 -
AGENT_CLIENT_ID: 代理 ID。 显示为AgentIdentity查询参数。 -
CLIENT_SPA_APP_ID:MSAL.js 用于浏览器登录的 SPA 应用 ID(仅限 OBO)。 -
AWS_REGION: Bedrock 的 AWS 区域,例如us-east-2。 -
BEDROCK_MODEL_ID: 模型 ID。 默认值:us.anthropic.claude-3-haiku-20240307-v1:0。 -
VALIDATE_TOKEN_SIGNATURE: 默认值true。 将false设置为跳过天气 API 中的 JWKS 签名验证(仅限调试)。
-
根据您选择的等级输入 AWS 凭据:
-
层 A(STS):设置
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_SESSION_TOKEN。 -
第 B 层(API 密钥): 设置
AWS_BEARER_TOKEN_BEDROCK。 -
第 C 层(OIDC):通过平台应用设置进行配置,而不是在
.env。
-
层 A(STS):设置
Tip
如果你在上一个会话中已有 .env,则只需更新 AWS 凭证,因为 STS 令牌约一小时后会过期。 直接跳到 “启动堆栈”。
启动堆栈
验证 Docker Desktop(或 Docker 引擎)是否在计算机上运行。
生成容器映像,并在分离模式下启动所有三个服务(代理、sidecar 和天气 API):
docker compose up --build -d通过查询状态终结点检查所有容器是否已成功启动。 该响应会指示代理是否能够连接到 AWS Bedrock:
Bash:
curl http://localhost:3001/api/statusPowerShell:
Invoke-RestMethod http://localhost:3001/api/status你会看到一个响应指示
bedrock_available: true(如果你使用不带 AWS 凭据的 Direct 模式则为false)。
Important
更新 .env 时(例如刷新过期的 STS 凭据), docker compose restart 不会重新加载环境变量。 改用 docker compose up -d --force-recreate llm-agent-aws。
通过聊天 UI 发送查询
在浏览器中打开
http://localhost:3001。使用标题栏配置演示:
-
执行模式:
Direct(跳过 LLM)或Bedrock(Claude 上的 LangChain ReAct 代理)。 -
标识流:
Autonomous(仅应用令牌)或OBO(代表已登录用户操作)。
-
执行模式:
如果选择 OBO,请选择 “登录 ”以通过 MSAL.js 弹出窗口进行身份验证。
键入 “达拉斯天气” 之类的查询,然后选择“ 发送”。
观看右侧的 “标识跟踪 ”面板,了解每个令牌交换和 API 调用的分步细分。 面板显示每个令牌(Tc、T1、TR)的彩色编码 JWT 卡片,包含解码后的声明。
排查常见问题
如果某些内容未按预期工作,请检查下表中是否存在常见问题和修补程序:
| 症状 | 可能的原因 | 修复 |
|---|---|---|
/api/status 显示 bedrock_available: false |
AWS 凭据缺失或过期,或者未授予模型访问权限。 | 请检查 docker logs llm-agent-aws。 使用 aws sso login 刷新 STS 凭据。 在 Bedrock 控制台中启用模型。 |
ExpiredTokenException 从贝德洛克 |
STS 会话令牌(A级)已过期。 | 将新凭据粘贴到 .env其中,然后运行 docker compose up -d --force-recreate llm-agent-aws。 |
AccessDeniedException 在 InvokeModel 上 |
IAM 主体缺少 bedrock:InvokeModel 权限,或未启用模型访问。 |
授予 bedrock:InvokeModel 对模型和推理配置文件 ARN 的权限。 |
ValidationException: invalid model identifier |
区域未托管模型,或者使用了裸模型 ID 而不是 us. 推理配置文件。 |
使用us.前缀的推理配置文件 ID(例如us.anthropic.claude-3-haiku-20240307-v1:0)。 |
天气 API 返回 401 Unauthorized |
令牌租户不匹配、过期的密钥或签名检查失败。 | 验证 TENANT_ID 是否与蓝图的租户匹配。 检查 sidecar 日志。 |
| 大语言模型响应但未调用工具 | 查询看起来不像工具,或者模型不支持工具调用。 | 使用 Claude 3 Haiku 或更高版本。 将请求短语为“城市<中的>天气是什么?” |
| OBO 登录弹出窗口被阻止 | 浏览器弹出窗口阻止程序。 | 允许弹出窗口。localhost:3001 |
OBO 期间来自边车的 4xx |
CLIENT_SPA_APP_ID 缺少,或 SPA 重定向 URI 不匹配。 |
重新运行 setup-obo-client-app。 确保 http://localhost:3001 位于 SPA 的重定向 URI 上。 |
如果在执行故障排除步骤后仍存在问题,请直接检查容器日志。 每个服务都将日志记录到各自的容器中:
docker logs llm-agent-aws # Agent app: Bedrock calls, tool invocations
docker logs agent-id-sidecar-aws # Sidecar: token acquisition, credential errors
docker logs weather-api-aws # Weather API: JWT validation, request handling
清理资源
完成测试后,停止本地容器以释放系统资源。 根据您是否希望保留映像以加快重启速度,选择以下清理选项之一。
Important
docker compose down 仅删除本地 Docker 容器。 Microsoft Entra 对象(智能体蓝图、智能体 ID、SPA 应用注册)属于租户侧状态,并会持续存在。 如果不再需要它们,请在Microsoft Entra 管理中心中手动删除它们。
# Stop containers but keep volumes and images for faster restarts
docker compose down
# Remove everything including volumes and images
docker compose down -v --rmi all
相关内容
- 使用 Microsoft Entra ID 身份验证 SDK 进行身份验证 (sidecar)
- 与Microsoft Entra代理ID集成第三方代理
- Microsoft Entra ID 身份验证 SDK (sidecar) 容器映像