Files
moss-ai/mcp/didatodolist-mcp/utils/asgi_auth.py
雷雨 8635b84b2d init
2025-12-15 22:05:56 +08:00

43 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
简单的 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)