This commit is contained in:
雷雨
2025-12-15 22:05:56 +08:00
commit 8635b84b2d
230 changed files with 53888 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
"""
简单的 ASGI 中间件:为 SSE 入口添加 x-api-key 鉴权。
当前 fastmcp 版本不支持 authenticate 参数时,可通过该中间件实现最小可用的 Header 鉴权。
"""
from typing import Callable, Awaitable
import os
class ApiKeyAuthMiddleware:
def __init__(self, app, header_name: str = "x-api-key", expected_key: str | None = None, sse_path: str = "/sse"):
self.app = app
self.header_name = header_name.lower()
self.expected_key = expected_key or os.environ.get("MCP_API_KEY", "123")
self.sse_path = sse_path
async def __call__(self, scope, receive, send):
# 仅对 HTTP scope 且 SSE 路径做校验,其余直接放行
if scope.get("type") == "http":
path = scope.get("path", "")
if path.startswith(self.sse_path):
# 提取 headerbytes
headers = {k.decode("latin1").lower(): v.decode("latin1") for k, v in scope.get("headers", [])}
api_key = headers.get(self.header_name)
if api_key != self.expected_key:
body = b"Unauthorized: missing or invalid x-api-key"
await send({
"type": "http.response.start",
"status": 401,
"headers": [(b"content-type", b"text/plain; charset=utf-8")],
})
await send({
"type": "http.response.body",
"body": body,
"more_body": False,
})
return
return await self.app(scope, receive, send)
def with_api_key_auth(app, header_name: str = "x-api-key", expected_key: str | None = None, sse_path: str = "/sse"):
return ApiKeyAuthMiddleware(app, header_name=header_name, expected_key=expected_key, sse_path=sse_path)