Token导航 LogoToken导航TokenDH.com
Dotnet Entra Id logo
AI代理未说明官方级别未说明来源级核验

Dotnet Entra Id

MCP Server

一个基于.NET的安全MCP服务器样板,集成Microsoft Entra ID认证,提供动态客户端注册、OAuth 2.1代理和用户声明管理功能,适用于企业环境中Claude AI和ChatGPT的安全集成。

工具数

1

提示词数

0

GitHub Stars

3

资源数

0
C#ClaudeAI代理Claude DesktopClaudeVS Code

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

Profility-be

提供方

Profility-be

最后核验

2026/5/17 20:20

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

MCP服务器正在使用。网络和微软Entra ID

A.NET样板,用于构建与Microsoft Entra ID集成的安全MCP服务器。

此项目为任何想要快速设置使用Microsoft Entra ID(Azure AD)保护的模型上下文协议(MCP)服务器的人提供了一个即用型基础。 它包括对组织中的用户进行身份验证、安全管理用户身份以及在受信任的企业环境中公开MCP工具所需的所有核心组件。

开箱即用,它经过测试并与Claude AI和ChatGPT兼容,使其成为在几分钟内让您自己的Entra保护的MCP服务器运行的最快方法。

该项目演示了如何弥合MCP客户端(Claude AI、ChatGPT)和Microsoft Entra ID之间的身份验证差距,确保这些系统能够安全无缝地协同工作。

![License: MIT](../LICENSE) ![.NET](https://dotnet.microsoft.com/download)

A.NET 8.0示例实现,展示了如何构建OAuth 2.1代理,使Claude AI能够使用Microsoft Entra ID对模型上下文协议(MCP)服务器进行身份验证。

______________________________________________________________________

概述

该项目演示了如何弥合Claude AI和Microsoft Entra ID(Azure AD)之间的身份验证差距。克劳德要求 RFC 7591动态客户端注册,Entra ID不支持。此代理在维护企业安全的同时,在这些不兼容的系统之间进行转换。

与官方合作建造 模型上下文协议C#SDK -此SDK是在中实现MCP服务器的游戏规则改变者。NET,提供强类型接口和自动协议处理。

┌──────────┐      OAuth 2.1       ┌──────────────────────┐      OAuth 2.0      ┌────────────┐
│          │  (with Dynamic Reg)  │                      │   (Pre-registered)  │            │
│ Claude   ├─────────────────────►│  MCP (OAuth) Server  ├────────────────────►│ Entra ID   │
│   AI     │◄─────────────────────┤   (this project)     │◄────────────────────┤            │
└──────────┘                      └──────────────────────┘                     └────────────┘
                                  

主要特点

  • 自定义登录UI -Entra ID认证前的品牌同意页面
  • WhoAmI工具 -显示经过身份验证的用户信息的示例MCP工具
  • 动态客户端注册 -实现RFC 7591以实现克劳德兼容性
  • 双PKCE流 -所有组件之间的安全身份验证(RFC 7636)
  • 令牌映射 -不透明的外部令牌,带有用户声明的JWT内部令牌
  • 用户索赔提取 -Entra ID令牌中的姓名、电子邮件、OID、UPN
  • 生产就绪 -CORS、HTTPS、错误处理、结构化日志

截图

OAuth login flow with custom branding before Entra ID authentication

*OAuth login flow with custom branding before Entra ID authentication*

测试平台

✅ 克劳德·艾 -经过全面测试,可使用Claude Desktop和web界面

✅ ChatGPT -经过测试并正常工作;有关动态客户端注册和持久客户端存储要求的说明,请参阅故障排除。

⚠️ 其他MCP客户端 -此代理实现了MCP OAuth规范。虽然它可能与其他MCP客户端一起工作,但它主要经过了Claude AI和ChatGPT的测试。VS Code的MCP集成通常使用带有预配置客户端凭据的直接OAuth,可能不需要此代理

______________________________________________________________________

包含内容

带OAuth的MCP服务器

该项目包括一个完整的MCP服务器实现,包括:

  • WhoAmI工具 -显示经过身份验证的用户信息
  ✅ Authentication Status: Authenticated via Entra ID OAuth
  📋 User Information:
    • Name: John Doe
    • Email: john.doe@company.com
    • User ID (OID): b9b8d416-d882-47f9-bb74-445d22ddd735
    • UPN: john.doe@company.com
  • OAuth保护的端点 -所有MCP端点都需要有效的承载令牌
  • 用户上下文 -工具可以访问经过身份验证的用户声明以进行个性化

OAuth代理组件

  • 动态客户端注册 -接受Claude的注册请求
  • 授权流程 -自定义登录页面+Entra ID重定向
  • 代币交换 -将Entra ID令牌映射到具有正确受众的代理令牌
  • 发现端点 -符合RFC 9728和RFC 8414的元数据

______________________________________________________________________

快速开始

先决条件

  • ✅ .已安装NET 8.0 SDK
  • ✅ 带有Entra ID租户的Azure订阅
  • ✅ 创建应用程序注册的管理员权限
  • ✅ Visual Studio 2022、VS Code或Rider

备注:本项目使用官方 MCP C#SDK 这大大简化了MCP服务器的实现。

1.克隆和构建

git clone 
cd MCP
dotnet build

2.Azure应用程序注册设置

  1. 首选 Azure 门户 > 参赛者ID > 应用注册 > 新注册
  1. 配置应用程序:

- 名字: MCP OAuth Proxy - 支持的帐户类型: Accounts in this organizational directory only - 重定向URI: Web - https://YOUR-DOMAIN/oauth/callback - 对于生产:使用您部署的URL(例如。, https://your-app.azurewebsites.net/oauth/callback) - 对于DevTunnels:使用您的隧道URL(例如。, https://abc123-5248.euw.devtunnels.ms/oauth/callback)

  1. 创建后,请注意以下值:

- 应用程序(客户端)ID - 目录(租户)ID

  1. 创建客户端密码:

- 首选 证书和秘密 > 新客户机密 - 描述: MCP Proxy Secret - 过期:选择合适的持续时间 - 复制机密值 (仅显示一次)

  1. 配置API权限:

- 首选 API权限 > 添加权限 - 选择 Microsoft Graph > 委托权限 - 添加: openid, profile, email, User.Read - 点击 授予管理员同意

备注: User.Read 基本身份验证并不严格要求,但通常使用,并支持未来可能需要调用Microsoft Graph API的场景(例如,获取用户照片、日历数据等)。

  1. 公开API(用于令牌受众):

- 首选 公开API > 添加作用域 - 应用程序ID URI: api://YOUR-CLIENT-ID (默认值很好) - 作用域名称: MCP.Access - 谁可以同意: Admins and users - 管理员同意显示名称: Access MCP Server - 管理员同意说明: Allows the application to access MCP tools on your behalf

3.生成安全密钥

运行密钥生成脚本:

.\GenerateKeys.ps1

将生成的值复制到配置中。

4.配置应用程序设置

{
  "MCP": {
    "ServerUrl": "https://YOUR-DOMAIN"
  },
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "YOUR-TENANT-ID",
    "ClientId": "YOUR-CLIENT-ID",
    "ClientSecret": "YOUR-CLIENT-SECRET",
    "Scope": "api://YOUR-CLIENT-ID/MCP.Access"
  },
  "Jwt": {
    "SigningKey": "GENERATED-SIGNING-KEY",
    "EncryptionKey": "GENERATED-ENCRYPTION-KEY",
    "ExpirationMinutes": "60"
  },
  "TokenStore": {
    "Provider": "InMemory",
    "AzureTableStorage": {
      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=YOUR_ACCOUNT;AccountKey=YOUR_KEY;EndpointSuffix=core.windows.net",
      "TableName": "TokenMappings"
    }
  },
  "ClientStore": {
    "Provider": "InMemory",
    "AzureTableStorage": {
      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=YOUR_ACCOUNT;AccountKey=YOUR_KEY;EndpointSuffix=core.windows.net",
      "TableName": "ClientRegistrations"
    }
  }
}

重要:

  • 替换 YOUR-DOMAIN 使用您的实际域名(例如。, https://your-app.azurewebsites.net)
  • 对于DevTunnels的本地开发,请使用您的隧道URL(例如。, https://abc123-5248.euw.devtunnels.ms)-见下面的步骤6
  • 替换 YOUR-TENANT-ID, YOUR-CLIENT-ID, YOUR-CLIENT-SECRET 使用Azure应用程序注册中的值
  • 使用由生成的密钥 GenerateKeys.ps1 为了 SigningKeyEncryptionKey

令牌存储选项:

  • InMemory (默认)-用于内存存储,适用于开发和单实例部署
  • AzureTableStorage -使用Azure表存储跨多个实例进行持久、可扩展的令牌存储

- 配置 ConnectionString 使用您的Azure存储帐户连接字符串 - TableName 默认为 TokenMappings 如果未指定 - 启动时自动创建表 - 每次应用程序重启时,过期的令牌(>90天)都会被清理

客户端存储选项:

  • InMemory (默认)-使用确定性客户端ID(SHA-256哈希),适合开发
  • AzureTableStorage -使用Azure表存储进行持久客户端注册

- 配置 ConnectionString 使用您的Azure存储帐户连接字符串 - TableName 默认为 ClientRegistrations 如果未指定 - 对客户端ID使用随机GUID - ChatGPT需要 -ChatGPT只注册一次,需要持久的客户端ID

5.运行服务器

dotnet run

服务器将在以下时间启动 https://localhost:5248 (或您配置的端口)。

6.利用DevTunnels进行当地开发(可选)

对于Claude AI的本地测试,您可以使用Microsoft DevTunnels来公开您的本地服务器:

# 1. Install Dev Tunnels CLI (one-time setup)
winget install Microsoft.devtunnel

# 2. Verify installation
devtunnel --version

# 3. Log in (one-time setup for tunnel management)
devtunnel user login

# 4. Create a persistent tunnel with anonymous access
devtunnel create -a

# 5. Map your local HTTPS app on port 5248 to the tunnel
devtunnel port create -p 5248 --protocol https

# 6. Start the tunnel
devtunnel host

隧道启动后:

  • 使用 “通过浏览器连接:” URL作为您的 MCP:ServerUrlappsettings.json
  • 将此URL作为重定向URI添加到您的Entra ID应用程序注册中(https://YOUR-TUNNEL-URL.devtunnels.ms/oauth/callback)
  • 配置Claude AI时使用此URL
  • “检查网络活动:” URL可用于监控Claude和MCP服务器之间的流量

DevTunnel URL示例: https://abc123-5248.euw.devtunnels.ms

7.配置Claude AI

  1. 打开 克劳德桌面 或前往 claude.ai
  2. 引导到 设置 > 连接 (或同等)
  3. 点击 添加集成添加自定义连接器
  4. 请输入您的服务器URL: https://YOUR-DOMAIN (或用于本地测试的DevTunnel URL)
  5. 点击 连接
  6. 您将被重定向到登录页面,然后是Entra ID
  7. 身份验证后,您将看到✅ 连接 在克劳德

8.测试连接

在Claude中,尝试:

Use the WhoAmI tool to show my information

您应该从Entra ID中看到您的姓名、电子邮件和其他声明。

______________________________________________________________________

项目结构

MCP/
├── Controllers/
│   ├── OAuthController.cs          # OAuth endpoints (authorize, continue, cancel, callback, token, register)
│   └── WellKnownController.cs      # Discovery endpoints
├── Services/
│   ├── PkceStateManager.cs         # Encrypted state for PKCE flows
│   ├── InMemoryLoginTokenStore.cs  # Short-lived login page tokens
│   ├── BrandingProvider.cs         # Branding configuration provider
│   ├── ConfigurationHelper.cs      # Configuration helper utilities
│   ├── ClientStore/
│   │   ├── AzureTableClientStore.cs # Azure Table Storage client store
│   │   ├── InMemoryClientStore.cs  # In-memory client store for development
│   │   └── IClientStore.cs         # Client store interface
│   ├── Jwt/
│   │   ├── DefaultClaimProvider.cs # Default JWT claim provider
│   │   ├── IClaimProvider.cs       # Interface for claim providers
│   │   ├── JwtBuilder.cs           # JWT token building utilities
│   │   └── SampleClaimProvider.cs  # Sample implementation of claim provider
│   └── TokenStore/
│       ├── AzureTableTokenStore.cs # Azure Table Storage token store
│       ├── InMemoryTokenStore.cs   # In-memory token store for development
│       └── ITokenStore.cs          # Token store interface
├── Models/
│   ├── PkceStateData.cs            # PKCE state data
│   ├── TokenData.cs                # Unified token model (authorization_code + refresh_token)
│   ├── LoginTokenData.cs           # Login page data
│   ├── ClientMapping.cs            # Client registration data
│   └── LoginPageModel.cs           # Login page view model
├── Tools/
│   └── WhoAmITool.cs               # Example MCP tool
├── Views/
│   ├── _ViewImports.cshtml         # Razor view imports
│   └── Login/
│       └── Index.cshtml            # Custom login UI
├── wwwroot/css/
│   └── login.css                   # Login page styling
├── Properties/
│   ├── launchSettings.json         # Launch settings for development
│   └── PublishProfiles/            # Publish profiles
├── Program.cs                      # ASP.NET Core configuration
├── appsettings.json                # Configuration
├── appsettings.Development.json    # Development configuration
├── MCP.csproj                      # Project file
├── GenerateKeys.ps1                # Key generation script
├── README.md                       # This file
└── README-Architecture.md          # Technical architecture details

______________________________________________________________________

身份验证流程

1. Claude → GET /.well-known/oauth-protected-resource
           Discovers authorization server

2. Claude → POST /oauth/register
           Dynamic client registration
           ← Returns client_id

3. Claude → GET /oauth/authorize?client_id=...&code_challenge=...
           Starts authorization flow
           ← Shows custom login page with user consent
           [User clicks "Continue"]

4. Proxy  → POST /oauth/continue
           Redirects to https://login.microsoftonline.com/.../authorize
           User authenticates with Entra ID

5. Entra  → Redirects to /oauth/callback?code=...
           Authorization code returned

6. Proxy  → Exchanges code with Entra ID
           ← Receives access_token + id_token

7. Proxy  → Generates proxy authorization code
           Redirects to https://claude.ai/api/mcp/auth_callback?code=...

8. Claude → POST /oauth/token (with code_verifier)
           Exchanges code for token
           ← Receives opaque access_token

9. Claude → GET /mcp/v1/tools (with Authorization: Bearer ...)
            Proxy validates token, forwards with JWT
            ← MCP server processes request

README-架构.md 获取详细的技术文档。

______________________________________________________________________

定制

品牌化

登录页面可以通过以下方式定制您自己的品牌 appsettings.json:

"Branding": {
  "CompanyName": "Profility",
  "ProductName": "Profility MCP Server",
  "PrimaryColor": "#6B46C1",
  "PrimaryHoverColor": "#553C9A"
}

这使您能够:

  • 公司名称:您的组织名称(以文本显示)
  • 产品名称:您的产品/服务名称(页面标题和描述)
  • 主色调:十六进制格式的主要品牌颜色(徽标、按钮)
  • 主悬停颜色:按钮悬停状态的阴影较深

品牌是通过以下方式配置的 appsettings.json -无需更改代码!

定制索赔

发放给Claude的JWT令牌可以通过索赔提供者系统扩展自定义索赔。这允许您向令牌添加特定于组织或特定于应用程序的声明。

它是如何工作的:

  • 实施 IClaimProvider 接口在 MCP/Services/Jwt/
  • 在中注册您的提供商 Program.cs 与默认提供者一起
  • 声明按注册顺序添加,实现了提供者之间的链接

有关更多信息,请参阅README-Architecture.md

______________________________________________________________________

故障排除

“客户端id无效”错误

  • 验证 AzureAd:ClientId 匹配Azure应用程序注册
  • 检查Azure中是否配置了重定向URI

“无效代码_验证器”错误

  • 表示PKCE验证失败
  • 检查数据保护密钥在重新启动时是否一致
  • 验证 Jwt:EncryptionKey 已配置

“无效受众”错误

  • 确保JWT aud 声明与MCP服务器URL匹配
  • 验证 Jwt:Audience 配置

令牌立即过期

  • 检查系统时钟同步
  • 验证令牌生命周期配置

用户声明缺失

  • 确保 openid profile email 作用域位于令牌请求中
  • 检查授予的入口ID API权限
  • 验证是否提供了管理员同意

ChatGTP问题: invalid_client 重新启动MCP服务后

当MCP服务重新启动时,ChatGPT可能会在OAuth流程中显示以下错误:

{
"error": "invalid_client",
"error_description": "Client not found"
}

原因: 这是因为 动态客户端注册(DCR) 客户端之间的行为不同:

  • 克劳德·艾 每当应用程序重新启动时,都会自动重新注册。
  • ChatGPT 仅执行DCR 一次,此时添加了连接器。\

之后,ChatGPT预计 client_id 无限期有效。

如果MCP服务器存储已注册的客户端 在存储器中,重新启动会清除客户端注册表,ChatGPT会继续发送旧的 client_id 不再存在,导致 invalid_client.

解决方案: 使用 持久客户端存储 在使用ChatGPT进行测试时,不使用内存存储:

"ClientStore": {
  "Provider": "AzureTableStorage",
  "AzureTableStorage": {
    "ConnectionString": "DefaultEndpointsProtocol=https;...",
    "TableName": "ClientRegistrations"
  }
}

这确保了注册 client_id 在应用程序重启后幸存下来,并防止OAuth握手失败。

ChatGTP问题:“连接器不安全”错误

问题描述: 在ChatGPT中连接自定义MCP服务器时,连接最初显示为成功。\ 连接器显示为 连接但是 没有可用的工具.\ 刷新工具(开发人员工具→ Network)披露了API响应:


{ "detail": "Connector is not safe" }

这个问题是 由MCP服务器、身份验证流、devtunnels或Entra ID引起。相反,ChatGPT在其 安全评估阶段,它扫描工具元数据(名称+描述)以查找任何建议访问的内容 个人数据 (PII)。

尽管服务器是完全安全的,但最初的工具描述明确提到\ 姓名、电子邮件、ID,这触发了ChatGPT的安全启发式,并导致它阻塞了连接器。

原因: 如果任何工具描述暗示连接器检索,ChatGPT会将其标记为“不安全” 用户身份, 电子邮件, 个人信息,或其他敏感数据——无论连接器是私有的还是受信任的。 安全检查仅在以下情况下运行 工具元数据,而不是你的实际实施。

解决方案: 重写工具描述,避免明确提及个人信息。\ 该工具仍可能在内部返回完整的身份详细信息——扫描仅评估元数据文本。

例子: 原始不安全描述:

Get information about the currently authenticated user (name, email, ID, etc.)

新的安全说明:

Returns basic operational context about the authenticated session.

安全考虑

⚠️ 生产部署检查表:

  • \[\]使用带有有效TLS证书的HTTPS
  • \[\]将机密存储在Azure密钥库或类似库中
  • \[\]对OAuth端点实施速率限制
  • \[\]仅对受信任的来源启用CORS
  • \[\]使用持久数据保护密钥存储(不在内存中)
  • \[ \] 使用Azure表存储进行令牌持久化 (包括在内,请参阅TokenStore配置)
  • \[\]实现令牌撤销
  • \[\]监视可疑的身份验证模式
  • \[\]定期安全更新和依赖关系扫描
  • \[\]实施适当的错误处理(错误中没有敏感数据)
  • \[\]使用短令牌寿命(建议1小时)

⚠️ 当前限制

此参考实现使用 内存存储 为简单起见,默认情况下:

  • PKCE 国家 -存储在静态中 ConcurrentDictionary (记忆中)
  • 令牌映射 -可配置: InMemory (默认)或 AzureTableStorage
  • 客户注册 -可配置: InMemory (默认)或 AzureTableStorage
  • 登录令牌 -存储在静态中 ConcurrentDictionary (记忆中)

用于生产部署,使用Azure表存储进行持久化:

  • Azure表存储令牌 -包括生产就绪令牌存储

- 集 TokenStore:ProviderAzureTableStorage 在应用程序设置中 - 启动时自动创建表 - 应用程序重启时过期令牌清理(>90天)

  • 客户端的Azure表存储 -包括生产就绪的客户端存储

- 集 ClientStore:ProviderAzureTableStorage 在应用程序设置中 - ChatGPT需要 兼容性(持久客户端ID) - 使用随机GUID而不是确定性哈希

  • 瑞迪斯 -分布式缓存的替代方案(不包括在内,请参阅架构文档)
  • SQL Server -审计跟踪要求的替代方案(不包括在内,请参阅架构文档)

______________________________________________________________________

文档

  • 建筑 -技术细节、OAuth流程、PKCE实现

______________________________________________________________________

贡献

欢迎投稿!此项目可作为MCP OAuth与企业身份提供者集成的参考实现。

需要改进的地方

  • 其他OAuth提供者实现(谷歌、Okta等)
  • 其他工具,如ChatGTP
  • 用于生产规模的Redis/SQL令牌存储
  • 令牌刷新实现
  • 更多MCP工具示例
  • 自动化测试

______________________________________________________________________

许可证

MIT许可证-有关详细信息,请参阅许可证文件

______________________________________________________________________

致谢

  • Anthropic -关于MCP规范和Claude AI
  • 模型上下文协议C#SDK -官方。NET实现使这个项目成为可能
  • 微软 -用于Entra ID和优秀的OAuth文档
  • 社区 -适用于OAuth 2.1、PKCE和相关RFC

______________________________________________________________________

维护者和贡献者

  • 罗尼·范德斯尼克(https://profility.be)

有兴趣贡献吗?请参阅上面的贡献部分或打开拉取请求。

______________________________________________________________________

支持

这是一个参考实现。对于问题:

  1. 检查上面的故障排除部分
  2. 审查 README-架构.md 了解技术细节
  3. 打开日志和配置问题(编辑机密!)

______________________________________________________________________

内置于❤️ 作为企业MCP OAuth集成的示例

目录标签

目录标签

C#ClaudeAI代理企业认证本地部署OAuth代理动态客户端注册MicrosoftEntraIDMCP协议

支持客户端

Claude DesktopClaudeVS Code

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

oauth

工具数量(toolCount,工具数)

1

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明oauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP