MCP逐步认证
此存储库演示了如何通过迭代步骤构建具有HTTP传输和JWT身份验证的MCP(模型上下文协议)服务器。
此回购是关于“MCP授权”的深入、循序渐进的博客文章的伴侣。请参阅以下内容:
第4部分(本系列的后期补充): MCP授权与动态客户端注册
MCP授权规范要求
下表显示了主要身份提供者对MCP授权规范所需的OAuth RFC的支持。
RFC要求摘要:
- PKCE:用于代码交换的证明密钥(OAuth 2.1要求)
- RFC 8414:OAuth 2.0授权服务器元数据
- RFC 7591:OAuth 2.0动态客户端注册协议
- RFC 8707:OAuth 2.0的资源指标
| 标识提供者 | PKCE | RFC 8414 | RFC 7591 | RFC 8707 |
|---|---|---|---|---|
| Okta | 是 | 是 | 是 | N0 |
| 身份验证0 | 是 | 是 | 有点 | 没有 |
| 钥匙斗篷 | 是 | 是 | 是 | 否 |
| 平联邦 | 是 | 是 | 是 | |
| ForgeRock | 是的 | 是的 | 有点 | |
| 谷歌OAuth | 是 | 否 | 否 | 不 |
| 微软Entra | 是 | 是 | 否 | 否 |
概述
该项目展示了如何使用以下工具构建安全的MCP服务器:
- 基于FastAPI的HTTP传输
- JWT令牌身份验证
- OAuth 2.0元数据端点
- 基于范围的授权
- 基于角色的访问控制
循序渐进
第一步:FastAPI基本框架
- 文件:
http-transport-steps/src/mcp_http/step1.py - 它添加了什么:具有健康端点的基本FastAPI应用程序
- 主要特点:
- FastAPI服务器设置 - 基本健康检查终点(/health) - MCP HTTP传输基础
步骤2:基本MCP请求处理
- 文件:
http-transport-steps/src/mcp_http/step2.py - 它添加了什么:MCP协议请求/响应处理
- 主要特点:
- MCP请求解析和验证 - 基本MCP响应结构 - /mcp MCP协议通信端点 - JSON-RPC风格的请求处理
步骤3:MCP工具和提示定义
- 文件:
http-transport-steps/src/mcp_http/step3.py - 它添加了什么:MCP工具和提示,无需调度
- 主要特点:
- 工具定义(echo, get_time) - 快速定义(greeting, help) - 工具和提示的MCP协议合规性 - 尚未实际执行工具
步骤4:MCP工具调度
- 文件:
http-transport-steps/src/mcp_http/step4.py - 它添加了什么:实际工具执行和及时处理
- 主要特点:
- 工具调度和执行 - 及时检索和处理 - 使用功能工具运行MCP服务器 - 无效请求的错误处理
第五步:JWT基础设施
- 文件:
http-transport-steps/src/mcp_http/step5.py - 它添加了什么:JWT公钥加载和JWKS端点
- 主要特点:
- 从文件加载公钥 - JWKS(JSON Web密钥集)端点(/.well-known/jwks.json) - 外部令牌生成脚本(generate_token.py) - 智威汤逊基础设施基础
步骤6:JWT令牌验证
- 文件:
http-transport-steps/src/mcp_http/step6.py - 它添加了什么:JWT身份验证中间件和实施
- 主要特点:
- JWT令牌验证中间件 - 身份验证强制执行 /mcp 端点 - 从令牌中提取用户上下文 - 对无效/丢失令牌的正确错误响应
步骤7:OAuth 2.0元数据端点
- 文件:
http-transport-steps/src/mcp_http/step7.py - 它添加了什么:受保护资源和授权服务器的OAuth 2.0元数据
- 主要特点:
- /.well-known/oauth-protected-resource 端点 - /.well-known/oauth-authorization-server 端点 - 使用OAuth元数据增强健康端点 - MCP响应中的OAuth元数据
步骤8:基于范围的授权
- 文件:
http-transport-steps/src/mcp_http/step8.py - 它添加了什么:权限检查和基于角色的访问控制
- 主要特点:
- check_permission 范围验证方法 - 基于角色的访问控制(管理员、用户、访客) - 403权限不足的禁止响应 - MCP操作的范围执行
步骤9:增强MCP集成(计划中)
- 它将添加什么:响应和经过身份验证的工具中的用户上下文
- 计划的功能:
- MCP响应标头/元数据中的用户上下文 - 具有用户感知行为的经过身份验证的工具 - 增强的MCP协议集成 - 基于用户身份的个性化响应
JWT令牌结构
JWT代币包括:
- 用户ID:用户的唯一标识符
- 范围:权限(例如。,
mcp:read,mcp:tools,mcp:prompts) - 角色:用户角色(例如。,
admin,user,guest) - 过期:令牌有效期
测试
每个步骤都包括一个相应的测试脚本(test_stepX.sh)这验证了:
- 基本功能
- JWT身份验证(步骤5+)
- 授权(步骤6+)
- OAuth元数据(步骤7+)
- 访问控制(步骤8+)
用法
先决条件
- 安装
uv: https://docs.astral.sh/uv/getting-started/installation/ - 导航到
http-transport-steps目录
紫外线下的跑步步骤
# Run any step using uv run
uv run step1
uv run step2
uv run step3
# ... etc使用环境配置运行步骤10
步骤10支持Keycloak和MCP服务器URL的基于环境的配置。您可以使用 --env 标志,或默认为 keycloak_direct.env.
提供了两个示例env文件:
keycloak_direct.env(如需直接进入Keycloak,请访问localhost:8080)keycloak_proxy.env(如需代理访问,请访问localhost:9090)
示例用法:
# Run step 10 with a specific env file (e.g., proxy)
uv run step10 --env keycloak_proxy.env如果缺少env文件或环境变量,服务器将恢复到合理的默认值(localhost:8080等)。
运行步骤11的注意事项
- 您需要运行step10-mcp服务器
- 您必须允许匿名客户端注册:
- 添加受信任的主机(检查密钥斗篷日志以获取正确的IP)
- 对于受信任的主机策略,您不需要在URI上进行匹配
- mcp的允许范围:读取等和aud映射器
- 然后运行step11客户端
uv run step11与mcp检查员一起运行
- 您需要使用config.yaml运行agentgateway
- uv运行步骤10-env密钥斗篷proxy.env
- 运行mcp-inspector UI(注意,一些auth东西坏了,现在,使用这个:https://github.com/christian-posta/mcp-inspector/tree/ceposta-patches)
- 然后按照一步一步的身份验证流程进行操作
mcp范围问题: https://github.com/modelcontextprotocol/inspector/issues/587
令牌生成
对于需要JWT身份验证的步骤5-8,您可以使用 generate_token.py 脚本:
uv run python generate_token.py --username alice --scopes mcp:read,mcp:tools
uv run python generate_token.py --username bob --scopes mcp:read,mcp:prompts
uv run python generate_token.py --username admin --scopes mcp:read,mcp:tools,mcp:prompts
uv run python generate_token.py --username guest --scopes ""Keycloak令牌生成
要快速获得测试步骤9/keycloak的令牌:
curl -X POST "http://localhost:8080/realms/mcp-realm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=mcp-test-client" \
-d "username=mcp-admin" \
-d "password=admin123" \
-d "scope=openid profile email mcp:read mcp:tools mcp:prompts" | jq -r '.access_token'
该脚本将输出一个JWT令牌,可用于 Authorization: Bearer 经过身份验证的请求的标头。
依赖项
- 快速 API
- PyJWT
- 密码学
- 优维康
该项目使用 uv 用于依赖关系管理 pyproject.toml 配置。
