MCP服务器OAuth兼容层

为在Azure容器应用中部署的MCP服务器提供与Microsoft Entra ID认证的OAuth兼容层,支持Cursor IDE集成。

  • by mario-guerra
  • Python
  • 云端部署
  • 1 星标
  • 更新于
在 GitHub 查看 mario-guerra/azure-mcp-entra-id-oauth

使用说明

用于Azure+Microsoft Entra ID的MCP服务器OAuth

一个完整的指南和参考实现,用于在具有Microsoft Entra ID身份验证的Azure容器应用程序上部署MCP(模型上下文协议)服务器,与Cursor IDE兼容。

问题

MCP规范要求通过RFC 8414、RFC 7591和RFC 8707支持OAuth。Microsoft Entra ID不支持这些。Cursor IDE(主MCP客户端)严格执行所有这些操作。此仓库提供了弥合差距的兼容层。

这是给谁的

  • 工程师 构建将部署到Azure并通过Cursor IDE访问的MCP服务器
  • AI编码代理 (Claude、GPT等)在Cursor或类似IDE中运行,负责向MCP服务器添加OAuth/Entra ID身份验证

此回购中有什么内容

docs/
├── README.md                          ← You are here
├── azure-mcp-oauth-guide.md           ← Step-by-step deployment guide
├── lessons-learned.md                 ← Gotchas, decision records, debugging playbook
└── reference/
    ├── oauth_compat.py                ← Drop-in OAuth compatibility layer
    ├── identity_middleware.py          ← Drop-in identity extraction middleware
    ├── example_server.py              ← Minimal wiring example
    └── requirements.txt               ← Python dependencies

从这里开始

我想… 读这个
了解架构并从头开始设置 Azuremcp-oauth-guide.md
知道哪里出了问题,为什么,所以我不再重复了 学习课程.md
将工作代码复制到我的项目中 参考文献/
调试损坏的OAuth流 第5节,已获得的租赁

快速开始

1.先决条件

  • 已部署MCP服务器的Azure容器应用程序
  • Microsoft Entra ID应用程序注册:
    • 重定向URI: cursor://anysphere.cursor-mcp/oauth/callback (在“移动和桌面”下)
    • 暴露API范围: access_as_user
    • 公共客户端流: 启用

2.将OAuth层添加到您的服务器

复制 reference/oauth_compat.py 和 reference/identity_middleware.py 然后将它们连接到您的项目中:

from oauth_compat import OAuthCompatConfig, OAuthCompatEndpoints
from identity_middleware import IdentityMiddleware

# Get the Starlette app from your FastMCP server
app = mcp.streamable_http_app()

# Add middleware dynamically based on environment
import os
from identity_middleware import IdentityMiddleware

app = mcp.streamable_http_app()

if os.environ.get("RUNNING_IN_PRODUCTION") == "true":
    app.add_middleware(IdentityMiddleware)
else:
    from dev_middleware import DevIdentityMiddleware
    app.add_middleware(DevIdentityMiddleware)

# Add OAuth endpoints
config = OAuthCompatConfig.from_env()
oauth = OAuthCompatEndpoints(config)
# ... add_route calls ...

看 引用/示例服务器.py 作为一个完整的最小示例。

3.配置Azure

# Set Easy Auth to AllowAnonymous (REQUIRED — see guide for why)
az containerapp auth update \
  --name <app> --resource-group <rg> \
  --unauthenticated-client-action AllowAnonymous

# Set environment variables
az containerapp update \
  --name <app> --resource-group <rg> \
  --set-env-vars \
    "OAUTH_RESOURCE_URL=https://<app>.azurecontainerapps.io" \
    "OAUTH_TENANT_ID=<tenant-id>" \
    "OAUTH_CLIENT_ID=<client-id>" \
    "OAUTH_ALLOWED_HOSTS=login.microsoftonline.com"

4.配置光标

{
  "mcpServers": {
    "your-server": {
      "url": "https://<app>.azurecontainerapps.io/mcp",
      "headers": {
        "Accept": "application/json, text/event-stream"
      }
    }
  }
}

5.验证

# All five should succeed before testing in Cursor
curl -s https://<app>/health                                          # → 200
curl -s https://<app>/.well-known/oauth-protected-resource | jq .     # → 200
curl -s https://<app>/.well-known/oauth-authorization-server | jq .   # → 200
curl -s -X POST https://<app>/oauth/register \
  -H "Content-Type: application/json" \
  -d '{}' | jq .                                                      # → 201
curl -D - -X POST https://<app>/mcp                                   # → 401 + WWW-Authenticate

AI代理说明

如果您是负责将Entra ID OAuth添加到MCP服务器的AI代理,请阅读 《租赁合同》第8节 第一。它包含:

  • 飞行前检查表(编写代码前要验证什么)
  • 实施检查表(操作的确切顺序)
  • 要避免的常见错误(7个具体的注意事项)
  • 测试顺序(按此确切顺序进行验证)

工作原理(30秒版)

  1. 发现:您的中间件返回401+元数据URL。游标获取发现文档。
  2. 注册:游标注册并获取 client_id.
  3. 授权:光标重定向到 /oauth/authorize。您的代理将作用域和302重写为Microsoft。
  4. 代币:用户登录后,Cursor在以下位置将代码替换为令牌 /oauth/token。您的代理验证客户端并重写作用域。
  5. MCP呼叫:游标调用 /mcpAzure验证令牌;中间件在调用工具之前验证主体和路径。

安全加固

此实施遵循 默认拒绝 为MCP量身定制的方法:

  • 严格规范:用途 posixpath.normpath 以及前导斜线折叠以阻止路径遍历(例如。, //mcp).
  • SSRF和开放重定向保护:所有上游调用(元数据发现和令牌交换)和浏览器重定向(授权)都严格按照主机分配列表进行验证。可通过以下方式配置 OAUTH_ALLOWED_HOSTS.
  • 客户端ID强制:验证 client_id 在令牌代理中防止冒充。
  • 生产隔离:开发旁路逻辑在 dev_middleware.py.

数据流图

下图说明了Cursor、兼容层和Azure Entra ID之间的交互。

sequenceDiagram
    participant C as Cursor IDE
    participant P as OAuth Compatibility Layer (Proxy)
    participant M as Identity Middleware
    participant E as Azure Entra ID (Microsoft)
    participant A as MCP App (Tools)

    Note over C, A: 1. OAuth Discovery & Registration
    C->>P: GET /.well-known/oauth-protected-resource
    P-->>C: 401 Unauthorized + metadata URL
    C->>P: GET /.well-known/oauth-authorization-server
    P-->>C: OIDC Metadata (proxied from Microsoft)
    C->>P: POST /oauth/register
    P-->>C: 201 Created + client_id

    Note over C, A: 2. Authorization Flow
    C->>P: GET /oauth/authorize?scope=...
    P->>C: 302 Redirect to Microsoft (with rewritten scope)
    C->>E: User Interaction / Login
    E-->>C: 302 Redirect back with Code

    Note over C, A: 3. Token Exchange
    C->>P: POST /oauth/token (code + client_id)
    P->>P: Validate client_id & Rewrite scope
    P->>E: POST /v2.0/token (Forwarded)
    E-->>P: Access Token + ID Token
    P-->>C: Access Token

    Note over C, A: 4. Secure Tool Call
    C->>M: POST /mcp (Bearer Token)
    Note right of M: Azure App Service validates Token
    M->>M: Normalize Path & Verify Identity
    M->>A: Call Tool (Context: authenticated user)
    A-->>M: Tool Result
    M-->>C: JSON Response

来源

github: 蔚蓝的mcp入口

许可证

麻省理工学院