Skip to main content
Glama
jwt_auth_usage.md8.62 kB
# FastMCP JWT 认证 - 使用指南 ## 1. 认证配置指南 ### 1.1 API密钥认证配置 1. 在Odoo后台导航至 `MCP管理` > `服务器` 菜单 2. 创建新服务器或编辑现有服务器 3. 在`安全配置`标签页中: - 勾选`启用认证` - 选择`认证方式`: **API密钥认证** - 填写`API密钥`字段 - 可选:在`允许的IP地址`字段每行输入一个IP地址,限制访问 ### 1.2 JWT认证配置 1. 在Odoo后台导航至 `MCP管理` > `服务器` 菜单 2. 创建新服务器或编辑现有服务器 3. 在`安全配置`标签页中: - 勾选`启用认证` - 选择`认证方式`: **JWT令牌认证** - 配置以下JWT参数(至少需要公钥或JWKS URI之一): - `JWT公钥`: 粘贴PEM格式的RSA公钥 - `JWKS URI`: 输入提供JWT密钥的JWKS端点URL - `JWT发行者`: 输入允许的令牌发行者标识符(可选) - `JWT受众`: 输入允许的令牌受众标识符(可选) - `JWT算法`: 默认为RS256,可根据需要修改 - 可选:在`允许的IP地址`字段每行输入一个IP地址,限制访问 ### 1.3 生成API密钥 使用以下Python代码生成安全的随机API密钥: ```python import secrets import string def generate_api_key(length=32): """生成指定长度的随机API密钥""" alphabet = string.ascii_letters + string.digits api_key = ''.join(secrets.choice(alphabet) for _ in range(length)) return api_key # 生成32位API密钥 api_key = generate_api_key() print(f"生成的API密钥: {api_key}") ``` ### 1.4 生成JWT密钥对 使用以下Python代码生成RSA密钥对(用于JWT签名与验证): ```python from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa def generate_rsa_key_pair(): """生成RSA密钥对,返回私钥和公钥的PEM格式字符串""" # 生成私钥 private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048 ) # 导出私钥为PEM格式 private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ).decode('utf-8') # 导出公钥为PEM格式 public_key = private_key.public_key() public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ).decode('utf-8') return private_pem, public_pem # 生成RSA密钥对 private_key, public_key = generate_rsa_key_pair() print(f"私钥 (保存在客户端用于签发JWT):\n{private_key}") print(f"\n公钥 (配置在MCP服务器用于验证JWT):\n{public_key}") ``` ## 2. 客户端调用指南 ### 2.1 使用API密钥认证 #### Python示例 ```python import requests def call_mcp_api_with_key(server_url, api_key, endpoint): """使用API密钥调用MCP API""" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } response = requests.get( f"{server_url}/{endpoint}", headers=headers ) return response.status_code, response.json() # 使用示例 server_url = "http://localhost:8069/mcp/server/1" api_key = "your_api_key_here" endpoint = "resources/list" status, data = call_mcp_api_with_key(server_url, api_key, endpoint) print(f"状态码: {status}") print(f"响应数据: {data}") ``` #### cURL示例 ```bash curl -X GET "http://localhost:8069/mcp/server/1/resources/list" \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" ``` ### 2.2 使用JWT认证 #### 创建JWT令牌(Python) ```python import jwt import time def create_jwt_token(private_key, issuer, audience, subject, expiry_hours=1): """创建JWT令牌""" # 当前时间戳 now = int(time.time()) # 构建JWT载荷 payload = { "iss": issuer, # 发行者 "aud": audience, # 受众 "sub": subject, # 主题(通常为用户ID) "iat": now, # 发行时间 "exp": now + (3600 * expiry_hours) # 过期时间 } # 使用私钥签名JWT token = jwt.encode(payload, private_key, algorithm="RS256") return token # 使用示例 private_key = """-----BEGIN PRIVATE KEY----- ...您的私钥内容... -----END PRIVATE KEY-----""" token = create_jwt_token( private_key=private_key, issuer="my-auth-service", audience="mcp-server", subject="user123", expiry_hours=1 ) print(f"JWT令牌: {token}") ``` #### 使用JWT令牌调用API(Python) ```python import requests def call_mcp_api_with_jwt(server_url, jwt_token, endpoint): """使用JWT令牌调用MCP API""" headers = { "Authorization": f"Bearer {jwt_token}", "Content-Type": "application/json" } response = requests.get( f"{server_url}/{endpoint}", headers=headers ) return response.status_code, response.json() # 使用示例 server_url = "http://localhost:8069/mcp/server/1" jwt_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." # 您的JWT令牌 endpoint = "resources/list" status, data = call_mcp_api_with_jwt(server_url, jwt_token, endpoint) print(f"状态码: {status}") print(f"响应数据: {data}") ``` #### cURL示例 ```bash curl -X GET "http://localhost:8069/mcp/server/1/resources/list" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" ``` ## 3. 故障排除 ### 3.1 常见错误与解决方案 | 错误消息 | 可能原因 | 解决方案 | |--------------------------|-----------------|--------------------------| | "无效的API密钥" | API密钥不匹配 | 检查API密钥是否正确配置,无多余空格或换行符 | | "无效或过期的JWT Bearer token" | JWT令牌签名验证失败或已过期 | 检查公钥配置是否正确,验证令牌是否过期 | | "Authorization头格式错误" | 认证头格式不正确 | 确保认证头格式为`Bearer <token>` | | "缺少Authorization头" | 请求中未包含认证头 | 添加包含正确令牌的Authorization头 | | "IP地址未授权访问" | 客户端IP不在白名单中 | 将客户端IP添加到服务器的IP白名单中 | | "JWT认证错误: 无效的发行者" | 令牌发行者与配置不匹配 | 确保令牌的iss字段与服务器配置匹配 | | "JWT认证错误: 无效的受众" | 令牌受众与配置不匹配 | 确保令牌的aud字段与服务器配置匹配 | ### 3.2 JWT令牌调试 使用[jwt.io](https://jwt.io/)在线工具可以帮助调试JWT令牌: 1. 访问[jwt.io](https://jwt.io/)网站 2. 将JWT令牌粘贴到"Encoded"文本框中 3. 网站会自动解码并显示令牌的头部和载荷内容 4. 可以在"Verify Signature"部分粘贴公钥和私钥以验证签名 ### 3.3 日志分析 启用调试级别日志查看认证过程详细信息: ```bash # 启动Odoo服务器时开启MCP服务器的调试日志 python odoo-bin --log-level=debug --log-handler=mcp_server:DEBUG ``` 检查日志中的认证相关消息,以帮助排查问题: ``` 2023-07-22 08:45:23,421 DEBUG mcp_server.services.fast_mcp_service: JWT认证: 开始验证令牌 2023-07-22 08:45:23,450 DEBUG mcp_server.services.fast_mcp_service: JWT认证: 验证失败 - 令牌已过期 ``` ## 4. 安全最佳实践 ### 4.1 密钥管理 1. **私钥保护**: - JWT签名私钥应妥善保管,避免泄露 - 考虑使用密钥管理系统或硬件安全模块(HSM) - 不要在代码或配置文件中明文存储私钥 2. **定期轮换密钥**: - API密钥:每90天更换一次 - JWT密钥对:每180天更换一次 ### 4.2 令牌安全性 1. **JWT最佳实践**: - 设置合理的过期时间(通常为几小时或一天) - 包含所有必要的声明(iss, sub, aud, exp, iat) - 避免在令牌中存储敏感信息 2. **传输安全**: - 始终通过HTTPS传输令牌 - 避免在URL参数中传递令牌 ### 4.3 其他安全措施 1. **IP白名单**: - 限制只有特定IP地址能访问服务 - 定期审核和更新白名单 2. **监控与告警**: - 监控认证失败事件 - 设置异常认证失败的告警阈值

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kaikongbj/odoo-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server