使用说明
使用Azure API管理的安全远程MCP服务器(实验)
Azure API管理层作为 AI网关 对于MCP服务器。
此示例实现了最新的 MCP授权规范
这是一个 时序图 了解流程。
将远程MCP服务器部署到Azure
-
注册
Microsoft.App资源提供者。- 如果您正在使用Azure CLI,请运行
az provider register --namespace Microsoft.App --wait. - 如果您正在使用Azure PowerShell,请运行
Register-AzResourceProvider -ProviderNamespace Microsoft.App。然后跑(Get-AzResourceProvider -ProviderNamespace Microsoft.App).RegistrationState一段时间后检查注册是否完成。
- 如果您正在使用Azure CLI,请运行
-
运行这个 雅匝德 命令来配置api管理服务、函数应用程序(带代码)和所有其他所需的Azure资源
azd up
使用MCP检查员进行测试
-
在一个 新终端窗口,安装并运行MCP检查器
npx @modelcontextprotocol/inspector -
按CTRL键单击可从应用程序显示的URL加载MCP Inspector web应用程序(例如。http://127.0.0.1:6274/#resources)
-
将运输类型设置为
SSE -
将URL设置为在之后显示的正在运行的API管理SSE终结点
azd up和 连接:https://<apim-servicename-from-azd-output>.azure-api.net/mcp/sse -
列出工具。单击工具,然后 运行工具.
技术架构概述
此解决方案在Azure上部署了安全的MCP(模型上下文协议)服务器基础架构。该体系结构实现了一个多层安全模型,Azure API管理作为处理身份验证、授权和请求路由的智能网关。
已部署的Azure资源
基础架构提供以下Azure资源:
核心网关基础设施
- Azure API管理(APIM) -公开OAuth和MCP API的中央安全网关
- 库存量单位:BasicV2(可配置)
- 身份:系统分配和用户分配的管理身份
- 目的:处理身份验证流、请求验证和后端服务的安全代理
后端计算
- Azure功能应用程序 -托管MCP服务器实现
- 运行时:Python 3.11关于Flex消费计划
- 认证:具有托管身份集成的功能级身份验证
- 目的:执行MCP工具和操作(本例中的代码段管理)
存储和数据
- Azure存储帐户 -提供多种存储功能
- 功能托管:存储功能应用程序部署包
- 应用数据:用于代码段存储的Blob容器
- 安全:配置了托管身份访问和可选的专用终结点
安全和身份
-
用户分配的托管身份 -启用安全的服务到服务身份验证
- 目的:允许Function App无秘密地访问存储和应用程序洞察
- 权限:存储Blob数据所有者、存储队列数据贡献者、监控指标发布者
-
入境者身份证申请登记 -OAuth2/OpenID连接客户端进行身份验证
- 目的:根据MCP规范启用第三方授权流
- 配置:启用了PKCE的公共客户端,具有自定义重定向URI
监测和可观察性
- 应用洞察 -提供遥测和监控
- 日志分析工作区 -集中式日志记录和分析
可选网络安全
- 虚拟网络(ExpressRoute) -何时
vnetEnabled是真的- 专用端点:与存储帐户的安全连接
- 网络隔离:功能和存储通过专用网络进行通信
为什么这些资源?
Azure API管理 作为安全边界,实施:
- OAuth 2.0/PKCE身份验证流程符合MCP规范
- 用于安全访问API的会话密钥加密/解密
- 请求验证和标头注入
- 速率限制和节流功能
- 集中策略管理
Azure功能 提供:
- 无服务器、按使用付费的计算模型
- 与Azure服务的本地集成
- 根据需求自动缩放
- 内置监测和诊断
管理身份 消除以下需求:
- 服务凭据管理
- 秘密轮换流程
- 凭证风险
Azure API管理配置详细信息
APIM实例配置了两个主要API,它们协同工作以实现MCP授权规范:
OAuth API(/oauth/*)
此API实现MCP规范要求的完整OAuth 2.0授权服务器功能:
端点和操作
授权端点 (GET /authorize)
- 目的:启动OAuth 2.0/PKCE流
- 政策逻辑:
- 从MCP客户端请求中提取PKCE参数
- 检查现有用户同意(通过Cookie)
- 如果未授予同意,则重定向到同意页面
- 为Entra ID通信生成新的PKCE参数
- 将身份验证状态存储在APIM缓存中
- 将用户重定向到Entra ID进行身份验证
同意管理 (GET/POST /consent)
- 目的:处理用户对MCP客户端访问的同意
- 特性:通过安全Cookie保持同意
OAuth元数据端点 (GET /.well-known/oauth-authorization-server)
- 目的:根据RFC 8414发布OAuth服务器配置
- 退货:关于支持的端点、流和功能的JSON元数据
客户注册 (POST /register)
- 目的:支持根据MCP规范进行动态客户端注册
令牌端点 (POST /token)
- 目的:交换访问令牌的授权码
- 政策逻辑:
- 验证MCP客户端的授权码和PKCE验证器
- 交换访问令牌的Entra ID授权码
- 生成用于MCP API访问的加密会话密钥
- 使用会话密钥映射缓存访问令牌
- 将加密的会话密钥返回给MCP客户端
命名值和配置
OAuth API使用多个APIM命名值进行配置:
McpClientId-注册的Entra ID应用程序客户端IDEntraIDFicClientId-用于令牌交换的服务身份客户端IDAPIMGatewayURL-回调和元数据端点的基本URLOAuthScopes-请求的OAuth作用域(openid+微软图形)EncryptionKey/EncryptionIV-用于会话密钥加密
MCP API(/mcp/*)
此API为实际的MCP协议端点提供安全强制:
端点和操作
服务器发送事件终结点 (GET /sse)
- 目的:为MCP协议建立实时通信信道
- 安全:需要有效的加密会话令牌
消息端点 (POST /message)
- 目的:处理MCP协议消息和工具调用
- 安全:需要有效的加密会话令牌
安全策略实施
MCP API将全面的安全策略应用于所有操作:
-
授权标头验证
<check-header name="Authorization" failed-check-httpcode="401" failed-check-error-message="Not authorized" ignore-case="false" /> -
会话密钥解密
- 从授权标头中提取加密的会话密钥
- 使用AES和存储密钥和IV进行解密
- 验证令牌格式和结构
-
令牌缓存查找
<cache-lookup-value key="@($"EntraToken-{context.Variables.GetValueOrDefault("decryptedSessionKey")}")" variable-name="accessToken" /> -
访问令牌验证
- 验证缓存的访问令牌是否存在且有效
- 如果无效,则返回带有正确WWW-Authenticate标头的401
-
后端身份验证
<set-header name="x-functions-key" exists-action="override"> <value>{{function-host-key}}</value> </set-header>
安全模型
该解决方案实现了一个复杂的多层安全模型:
第1层:OAuth 2.0/PKCE身份验证
- MCP客户端必须使用Entra ID完成完整的OAuth流程
- PKCE防止授权码拦截攻击
- 具有持久偏好的用户同意管理
第二层:会话密钥加密
- 访问令牌永远不会暴露给MCP客户端
- 加密的会话密钥提供有时间限制的访问
- APIM中具有安全密钥管理的AES加密
第3层:功能级安全
- 函数主机密钥保护对Azure函数的直接访问
- 托管身份确保安全的服务到服务通信
- 通过ExpressRoute集成实现网络隔离
第4层:Azure平台安全
- 所有传输中加密的流量(TLS)
- 通过托管身份访问存储
- 通过Application Insights进行审核日志记录
这种分层方法确保了即使一个安全边界受到损害,也会保留多个额外的保护措施。
