你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。

工具箱身份验证在 Microsoft Foundry 中的工作原理

Microsoft Foundry 中的工具箱身份验证确定工具如何向下游服务进行身份验证。 身份验证设置在项目连接上配置,允许代理使用匿名访问、共享凭据、服务标识或登录用户的标识,而无需在代理代码中实现身份验证逻辑。

本文介绍工具箱身份验证的工作原理,并演示如何为专用 MCP 服务器和工作 IQ 配置 OAuth 标识直通,同时保留每个用户的权限和访问边界。

对于使用 MCP 和其他工具进行用户委派,请通过 Foundry 工具箱连接这些工具。 当将该工具箱添加到 Microsoft Agent Framework 托管的代理时,请在 Python 中使用 AddFoundryToolboxes,或在 .NET 中使用 FoundryToolbox。 请参阅 将工具箱与托管代理配合使用。

工具箱在连接上集中身份验证。 身份验证是连接的属性,而不是代理中的代码。 连接工具时,选择身份验证类型,Foundry 在服务端处理令牌获取、交换、刷新和注入。 代理代码仍侧重于业务逻辑,而不是身份验证流。

为什么每用户身份验证难以自行构建

如果你自行实现对受 Entra 保护工具的按用户访问控制,就必须承担关乎安全的底层集成工作,而这些细微之处很容易出错:

  1. 自行实现每个用户的令牌隔离。 必须按用户和租户对令牌缓存进行正确分区。 错误的缓存键可能会在不知不觉中将一个用户对下游 API 的访问权限泄露给另一个用户,而这种缺陷甚至能通过所有功能测试。
  2. 管理每个用户、每个资源的同意和生命周期。 你需要检测同意失败情况(例如 AADSTS65001),引导用户完成同意流程,刷新过期的令牌,并为编写的每个智能体中的每个 API 正确处理 401/403 重试。
  3. 轻松应对随工具和代理数量线性增长的复杂性。 每个新工具都会添加另一个范围、令牌交换、缓存条目、同意路径、重试路径和标头路径。 当扩展到数百种工具和数千个智能体时,你就不得不反复重建那些同样不牢靠的连接管道。

每次工具调用中的两个身份

要牢记的心智模型是:始终同时存在两个身份,而按用户进行的身份验证中所有棘手之处,都在于确保它们始终正确、彼此分离,并且绝不能在并发用户之间发生交叉混淆。

  • 代理到工具箱边界(稳定边界)。 代理使用自己的代理标识向平台进行身份验证。 该身份标识控制对工具箱本身的访问权限,而非其中各个工具的访问权限。
  • 工具与数据的边界(按用户划分的那个)。 在实际发起数据调用时,Foundry 会向下游服务提供代表当前登录用户的凭据。 根据身份验证类型,这些凭据来自 OAuth 授权流或特定受众的 Microsoft Entra 访问令牌。 下游服务仅返回用户可以访问的内容并遵循其权限和敏感度标签。

工具箱如何处理身份验证

工具箱将整个身份验证负担从代理端转移到连接层:

  • 身份验证位于连接上,而不是在代理中。 连接工具时,选择一次身份验证类型。 代理代码保持无身份验证状态。
  • Foundry 涵盖整个流程。 根据工具的需求,Foundry 存储并注入 API 密钥、获取服务标识的凭据、完成 OAuth 授权或提供特定于受众Microsoft Entra访问令牌。 Foundry 将每个用户凭据与其他用户隔离开来。
  • 只需构建业务逻辑。 身份验证流程从来都不是由你来构建的。
DIY 带来的负担 工具箱的作用
按用户令牌隔离 Foundry 自动隔离每个调用方的令牌。 不必担心把缓存键搞错。
按用户和资源分别进行同意和生命周期处理 Foundry 管理每个用户的同意流程和令牌生命周期,包括在获得所需同意后获取和刷新令牌。
认证按工具和团队分别重新实现 你只需使用其工具和身份验证配置构建一次工具箱,随后即可在所有代理和运行时中重复使用它。

在连接上设置身份验证类型

在门户中、使用 Azure Developer CLI 或通过 REST API 创建连接时,可以选择身份验证类型。 绝不要在代理代码中。 每种认证类型决定了哪一方的身份会传递给该工具:

authType 谁的身份信息会传递到该工具 将其用于
none 匿名 公共服务器(例如,Microsoft Learn MCP 服务器)。
custom-keys 存储的 API 密钥或标头 基于密钥的 SaaS。 代理永远不会看到机密。
project-managed-identity 项目的托管标识 无用户上下文的服务间调用
agentic-identity 代理自身的身份 针对每个代理的审计和最小权限。
oauth2 完成 OAuth 授权的用户 符合 OAuth 的服务,包括工作 IQ 和合作伙伴 MCP 服务器(例如 Vercel)。
user-entra-token 已登录的 Microsoft Entra 用户 需要特定受众 Entra 令牌的托管 Microsoft 服务,例如工作区专用的 Fabric 数据代理端点。

oauth2 和 user-entra-token 都支持按用户进行访问控制,但它们获取凭据的方式不同。 通过 oauth2,用户完成 OAuth 授权流程,Foundry 会存储并刷新由此获得的凭据。 借助 user-entra-token,Foundry 会向下游服务提供一个代表已登录用户的、面向特定受众的 Microsoft Entra 访问令牌。 使用服务所需的身份验证类型。

为每个身份验证类型配置连接

使用 azd ai connection create 注册每个连接。 命令形状始终相同;标志因身份验证类型而异。 将 --kind remote-tool 用于 MCP 和 A2A 服务器。

azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://public-mcp.example.com/mcp \
  --auth-type none

演练:OAuth 身份传递

此示例连接了两个受 Microsoft Entra 保护的工具,以实现按用户访问:一个是私有订单 MCP 服务器,另一个是 Work IQ。 两者都使用 OAuth 身份透传,因此每个下游调用都会以授权该连接的用户身份运行。

1.为每个工具创建连接

# Private orders MCP: OAuth identity passthrough
azd ai connection create orders-mcp \
  --kind remote-tool \
  --target https://orders-mcp.example.com/mcp \
  --auth-type oauth2 \
  --authorization-url https://auth.example.com/authorize \
  --token-url https://auth.example.com/token \
  --client-id <oauth-client-id> \
  --client-secret <oauth-client-secret> \
  --scopes "openid offline_access orders.read"

# Work IQ: OAuth identity passthrough
azd ai connection create workiq-conn \
  --kind remote-a2a \
  --target https://workiq.svc.cloud.microsoft/a2a/ \
  --auth-type oauth2 \
  --authorization-url https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize \
  --token-url https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
  --client-id <oauth-client-id> \
  --client-secret <oauth-client-secret> \
  --scopes "api://workiq.svc.cloud.microsoft/WorkIQAgent.Ask offline_access"

2. 将这两个工具添加到工具箱

每个工具通过 ID 引用其连接。 该单一引用是作为共享服务帐户运行和代表已登录用户执行操作之间的全部差异。 你的代理程序既不需要令牌代理服务,也不需要每用户令牌缓存。

此示例需要 azure-ai-projects (Python) 或 @azure/ai-projects (TypeScript) 2.3.0 或更高版本。

from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import MCPToolboxTool, WorkIQPreviewToolboxTool

endpoint = "https://<your-foundry-account>.services.ai.azure.com/api/projects/<your-project>"
project = AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential())
orders_connection = project.connections.get("orders-mcp")
workiq_connection = project.connections.get("workiq-conn")

toolbox_version = project.toolboxes.create_version(
    name="employee-toolbox",
    description="Private orders MCP + Work IQ, both via OAuth identity passthrough.",
    tools=[
        MCPToolboxTool(
            server_label="orders",
            server_url="https://orders-mcp.example.com/mcp",
            require_approval="never",
            project_connection_id=orders_connection.id,
        ),
        WorkIQPreviewToolboxTool(project_connection_id=workiq_connection.id),
    ],
)
print(f"Created toolbox: {toolbox_version.name}, version: {toolbox_version.version}")

对于 JavaScript,请参阅维护的 工具箱项目连接示例 和 Work IQ 示例。 第一个示例创建 MCP 支持的工具箱,该工具箱使用项目连接并将其附加到代理。 第二个示例演示了如何引用 Work IQ 项目连接。

3.将代理连接到工具箱

代理连接到工具箱的唯一消费者端点,该端点始终提供默认版本。 代理使用自己的标识向平台进行身份验证。 对于每个工具,Foundry 提供表示完成 OAuth 授权的用户的凭据。 该代理不带有针对每个工具的身份验证代码。

仅凭代理的凭据不足以进行按用户解析。 在 Python 中使用 FoundryToolbox,或在 .NET 中使用 AddFoundryToolboxes,并结合 Foundry 托管集成。 它会转发当前托管请求的 x-agent-foundry-call-id,以便工具箱代理能够确定调用方上下文。 不要对呼叫 ID 进行硬编码或跨用户请求重复使用。 该工具的连接还必须使用适当的每用户身份验证类型,并且用户需要下游权限和任何所需的许可。 有关托管设置,请参阅 将工具箱与托管代理配合使用。

from azure.identity import DefaultAzureCredential
from agent_framework import FoundryToolbox

# Agent-to-toolbox identity: the agent's own credential, scoped to the platform
credential = DefaultAzureCredential()
, timeout=120.0)

# Consumer endpoint always resolves to the toolbox's default version
CONSUMER_URL = f"{endpoint}/toolboxes/employee-toolbox/mcp?api-version=v1"

toolbox = FoundryToolbox(
    name="employee_toolbox",
    url=CONSUMER_URL,
    http_client=http_client,
    load_prompts=False,
)

agent = chat_client.as_agent(
    name="employee-agent",
    instructions="Help employees with their orders and Microsoft 365 context.",
    tools=[toolbox],
)

当特定用户首次需要授权工具时,Foundry 会生成同意链接。 在用户同意后,后续调用将使用该用户的凭据。 如果刷新令牌过期或已吊销,用户可能需要再次授权该工具。

注释

使用 OAuth 身份直通的代理的使用者,至少需要在该项目中具有 Foundry Agent Consumer 角色。 用户的Microsoft Entra租户必须与 Foundry 项目的租户匹配;不支持跨租户令牌交换。

超越传递:工具箱提供的其他功能

由于身份验证和工具流量都经工具箱流转,所以你得到的将不仅是干净利落的标识处理:

  • 负责任的 AI 防护措施。 护栏会筛选每个工具的输入和输出,因此不受信任的 MCP 响应无法将提示注入或不安全的内容走私回代理。
  • 自带 AI 网关。 使用 Azure API 管理 (APIM) 在 MCP 服务器前面设置速率限制、日志记录和网络策略。
  • 版本控制。 创建并测试新的工具箱版本,然后将其提升为默认值。 指向使用者终结点的每个代理都会自动选取升级的版本,无需更改代码。