mcpField
🤫
🤫 Authenticated Remote MCP Server

🤫 Authenticated Remote MCP Server

本地服务
github.com/localden开发工具3161 周前更新

关于 🤫 Authenticated Remote MCP Server

Authenticated Remote MCP Server 是一个示例项目,演示如何在 Azure 上部署受 Entra ID 保护的远程 MCP 服务。项目通过 Azure API Management 进行鉴权,并使用 OAuth 2.0 与 PKCE 流程。README 明确标注为实验性实现,不应用于生产环境。

主要功能

  1. 01基于 Entra ID 的远程 MCP 服务保护
  2. 02客户端先获取 MCP 服务令牌,再通过 OAuth on-behalf-of 流程访问 Microsoft Graph
  3. 03动态客户端注册与 PKCE 流程
  4. 04使用 __Host- 前缀的安全 Cookie 与 CSRF 防护
  5. 05通过 azd up 部署到 Azure

适用场景

  1. 01学习在 Azure 上部署受保护的远程 MCP 服务
  2. 02使用 MCP Inspector 测试 Entra ID 认证流程
  3. 03验证 Microsoft Graph 用户信息的获取方式

MCP 相关

该示例将远程 MCP 服务部署在 Azure 上,并通过 SSE 端点供 MCP Inspector 等 MCP 客户端连接,工具 get_graph_user_details 用于获取当前用户数据。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"remote-auth-mcp-apim-py": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/inspector"
]
}
}
}
启动命令npx -y @modelcontextprotocol/inspector

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@modelcontextprotocol/inspector

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

🤫 经过身份验证的远程 MCP 服务

此示例演示如何在 Azure 上部署受 Entra ID 保护的 MCP 服务。

此示例还采用了一种授权模式:客户端首先获取一个_用于 MCP 服务_的令牌,然后通过代表流将其兑换为可用于Microsoft Graph的令牌。整个过程也完全无需使用机密。

⚠️ 重要:实验性实现

重要

这是一个实验性实现,不应在生产场景中使用。

此示例演示如何通过实现 OAuth 2.0 动态客户端注册和 PKCE 流模式,在 Entra ID 的原生标准支持尚有不足的情况下,构建受 Entra ID 保护的 MCP 服务。此示例展示了技术上的可行性,但仅用于教育和概念验证。

对于生产场景,请考虑使用已注册应用和标准 OAuth 流的成熟身份验证模式。

使用的技术

说明

你可以使用 Model Context Protocol Inspector 或 Visual Studio Code 测试此 MCP 服务。

授权流的工作方式

此实现使用带有 PKCE(代码交换证明)的高级 OAuth 2.0 流,对 MCP 客户端进行安全身份验证。以下是整个流程的运作方式:

sequenceDiagram
    participant Client as MCP Client
    participant Browser as User's Browser
    participant APIM as API Management
    participant Entra as Entra ID
    participant Function as Azure Function
    participant Graph as Microsoft Graph

    Note over Client,Graph: 1. Discovery & Registration
    Client->>APIM: GET /.well-known/oauth-authorization-server
    APIM->>Client: OAuth metadata (authorization_endpoint, token_endpoint, etc.)
    
    Client->>APIM: POST /register (Dynamic Client Registration)
    Note over APIM: Store client info in CosmosDB<br/>Generate unique client_id
    APIM->>Client: Client credentials (client_id, no secret)

    Note over Client,Graph: 2. Authorization with PKCE
    Note over Client: Generate code_verifier & code_challenge
    Client->>Browser: Open authorization URL with PKCE params
    Browser->>APIM: GET /authorize?client_id=...&code_challenge=...
    
    Note over APIM: Check for existing consent cookie<br/>🍪 __Host-MCP_APPROVED_CLIENTS
    alt No previous consent
        APIM->>Browser: Redirect to /consent page
        Note over Browser: User reviews permissions and clicks "Allow"
        Browser->>APIM: POST /consent (with CSRF protection)
        Note over APIM: Set consent cookie<br/>🍪 __Host-MCP_APPROVED_CLIENTS<br/>🍪 __Host-MCP_CONSENT_STATE
    end
    
    APIM->>Browser: Redirect to Entra ID with state correlation
    Note over APIM: Set Entra state cookie<br/>🍪 __Host-MCP_ENTRA_STATE<br/>(contains sessionId|entraidState|clientState)
    
    Browser->>Entra: Authorize with Entra ID
    Note over Browser: User authenticates with Entra ID
    Entra->>APIM: Callback with authorization code
    
    Note over APIM: Validate state correlation<br/>Exchange code for Entra access token<br/>Generate encrypted session token
    APIM->>Browser: Redirect with MCP authorization code

    Note over Client,Graph: 3. Token Exchange
    Browser->>APIM: POST /token (code + code_verifier)
    Note over APIM: Validate PKCE challenge<br/>Return encrypted session token
    APIM->>Browser: Access token (encrypted session key)
    Browser->>Client: Token for MCP communication

    Note over Client,Graph: 4. Authenticated MCP Communication
    Client->>APIM: GET /mcp/sse (with Bearer token)
    Note over APIM: Decrypt session token<br/>Lookup cached Entra token<br/>Add to request for downstream
    APIM->>Function: Forward with Entra access token
    
    Function->>Graph: API calls using on-behalf-of flow
    Graph->>Function: User data
    Function->>APIM: MCP response
    APIM->>Client: Authenticated MCP response
安全功能与使用的 Cookie

此实现使用多种安全机制和 Cookie,确保流程安全:

Cookie用途
__Host-MCP_APPROVED_CLIENTS记住用户对特定客户端的授权
__Host-MCP_DENIED_CLIENTS记住被拒绝的授权,避免再次提示
__Host-MCP_CONSENT_STATE验证授权表单提交
__Host-MCP_ENTRA_STATE将 Entra ID 回调与原始请求关联起来
__Host-MCP_CSRF_TOKEN防止授权表单遭受 CSRF 攻击

说明

所有 Cookie 均使用 __Host- 前缀,并设置 Secure、HttpOnly 和 SameSite=Lax,以实现最高安全性(但 __Host-MCP_ENTRA_STATE 除外,它使用 SameSite=None 进行跨站重定向)。

主要安全功能:

  • 🔐 PKCE(代码交换证明) - 防止授权码被截获
  • 🍪 安全 Cookie - 所有 Cookie 均使用 __Host- 前缀,以实现最高安全性
  • 🛡️ CSRF 防护 - 使用双重提交 Cookie 模式和恒定时间验证
  • 🔄 状态关联 - 多层状态验证可防止会话固定
  • 🔒 加密的会话令牌 - 会话标识符经过 AES 加密
  • ⏰ 令牌缓存 - 缓存 Entra 令牌,并使用加密的会话密钥提升性能

开始使用

按照以下步骤开始使用。

  1. 安装 Azure Developer CLI。

  2. 在本地克隆仓库:

    git clone https://github.com/localden/remote-auth-mcp-apim-py
    
  3. 在终端中进入仓库目录:

    cd remote-auth-mcp-apim-py
    
  4. 确保已在订阅中注册 Microsoft.App 资源提供程序,可通过 Azure 门户完成注册,也可运行以下 Azure CLI 命令:

    az login
    az provider register --namespace Microsoft.App --wait
    
  5. 登录 Azure Developer CLI:

    azd auth login
    
  6. 将项目部署到 Azure:

    azd up
    

重要

部署此项目会产生 Azure 费用。如果部署用于测试和实验,请务必在测试后删除创建的资源组。

部署和测试项目

运行 azd up 时,infra 目录中声明的资源将在你的 Azure 帐户中预配。你可以查看现有的 Bicep 文件,了解将自动部署哪些基础设施。

使用 Azure Developer CLI 部署 Azure 资源的 GIF

部署完成后,终端中会显示 endpoint:

终端中的终结点

例如,在上方的屏幕截图中,终结点是 https://apim-2lzunaz2nu642.azure-api.net/mcp/sse。复制它。

说明

执行下一步之前,请确保已安装 Node.js——运行 Model Context Protocol Inspector 需要它。

在终端中运行:

npx @modelcontextprotocol/[email protected]

说明

我们使用 Model Context Protocol Inspector 的 0.9.0 版本,因为在测试受保护的 MCP 服务时,这是最稳定的版本。

这将提供一个终结点,你可以通过它查看本地运行的 Model Context Protocol Inspector。在浏览器中打开该 URL。

将 Transport Type 切换为 SSE,并将 URL 设置为部署运行后获得的终结点。点击 Connect。

在 MCP Inspector 中进行身份验证

系统会提示你使用部署基础设施所在租户中的凭据进行身份验证。Entra ID 应用程序会在部署时动态注册:一个用于服务,另一个用于执行 on-behalf-of flow,以获取 Microsoft Graph 访问权限。

同意后,你将返回 Model Context Protocol Inspector 的首页。等待几秒钟,直到建立连接;页面上会显示绿色的 Connected 标签。

MCP Inspector 中已连接的 MCP 服务

连接后,点击 List Tools,并选择 get_graph_user_details。这样即可从 Microsoft Graph 获取当前已通过身份验证的用户数据。点击 Run Tool。

在 MCP Inspector 中列出工具并触发返回 Graph 用户详细信息的工具

如果一切顺利,你会在响应区域中看到用户数据,如下所示:

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "businessPhones": [],
  "displayName": "YOUR_NAME",
  "givenName": null,
  "jobTitle": null,
  "mail": "YOUR_EMAIL",
  "mobilePhone": null,
  "officeLocation": null,
  "preferredLanguage": null,
  "surname": null,
  "userPrincipalName": "YOUR_UPN",
  "id": "c6b77314-c0ec-44b2-b0bb-2c971a753f0c",
  "success": true
}

反馈和问题报告

如果遇到任何阻碍或有意见,请务必提交问题。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。