在 MCP 服务器中配置 Bearer 认证 (Authentication)
MCP Auth 提供多种方式在你的 MCP 服务器中配置 Bearer 授权 (Authorization):
- JWT (JSON Web Token) 模式:内置的授权 (Authorization) 方法,通过声明 (Claims) 断言验证 JWT。
- 自定义模式:允许你实现自己的授权 (Authorization) 逻辑。
使用 JWT 模式配置 Bearer 认证 (Authentication)
如果你的 OAuth / OIDC 提供商为授权 (Authorization) 签发 JWT,你可以在 MCP Auth 中使用内置的 JWT 模式。它会验证 JWT 的签名、过期时间以及你指定的其他声明 (Claims);然后会在请求上下文中填充认证 (Authentication) 信息,供你的 MCP 实现进一步处理。
权限 (Scope) 校验
以下是基本权限 (Scope) 校验的示例:
- Python
- Node.js
from mcpauth import MCPAuth
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.routing import Mount
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("MyMCPServer")
mcp_auth = MCPAuth(
# Initialize with your auth server config
)
bearer_auth = mcp_auth.bearer_auth_middleware("jwt", required_scopes=["read", "write"])
app = Starlette(
routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)
import express from 'express';
import { MCPAuth } from 'mcp-auth';
const app = express();
const mcpAuth = new MCPAuth({
/* ... */
});
const bearerAuth = mcpAuth.bearerAuth('jwt', { requiredScopes: ['read', 'write'] });
app.use('/mcp', bearerAuth, (req, res) => {
// Now `req.auth` contains the auth info
console.log(req.auth);
});
在上面的示例中,我们指定 JWT 需要包含 read
和 write
权限 (Scopes)。如果 JWT 没有包含任意一个这些权限 (Scopes),请求将被拒绝并返回 403 Forbidden 错误。
资源指示器 (Resource indicator) 校验(RFC 8707)
如果你的提供商基于 OIDC,或支持 资源指示器 (Resource Indicator) 扩展,你还可以指定 audience
选项来校验 JWT 中的 aud
(受众 (Audience))声明 (Claim)。这有助于确保 JWT 是专门为你的 MCP 服务器签发的。
请查阅你的提供商文档,了解是否支持资源指示器 (Resource Indicator) 扩展以及如何配置。有些提供商可能会用“audience”、“API 资源 (API resource)”或“API indicator”等术语来指代同一概念。
配置好资源指示器 (Resource indicator) 后,你可以在 bearerAuth
中间件中指定它:
- Python
- Node.js
bearer_auth = mcp_auth.bearer_auth_middleware(
"jwt",
audience="https://api.example.com/mcp", # JWT 期望的受众 (Audience)
required_scopes=["read", "write"]
)
const bearerAuth = mcpAuth.bearerAuth('jwt', {
audience: 'https://api.example.com/mcp', // JWT 期望的受众 (Audience)
requiredScopes: ['read', 'write'],
});
在上面的示例中,MCP Auth 会同时校验 JWT 的 aud
声明 (Claim) 和所需的权限 (Scopes)。
为 JWT 校验提供自定义选项
你还可以为底层的 JWT 校验库提供自定义选项:
- Python
- Node.js
在 Python SDK 中,我们使用 PyJWT 进行 JWT 校验。你可以使用以下选项:
leeway
:在校验 JWT 过期时间时允许一定的宽限时间(秒)。默认是 60 秒。
bearer_auth = mcp_auth.bearer_auth_middleware(
"jwt",
audience="https://api.example.com/mcp",
required_scopes=["read", "write"]
leeway=10, # 允许 10 秒的宽限时间以减少时钟偏差
)
在 Node.js SDK 中,我们使用 jose 库进行 JWT 校验。你可以提供以下选项:
jwtVerify
:JWT 校验过程的选项(jose
的jwtVerify
函数)。remoteJwtSet
:获取远程 JWT 集合的选项(jose
的createRemoteJWKSet
函数)。
const bearerAuth = mcpAuth.bearerAuth('jwt', {
audience: 'https://api.example.com/mcp',
requiredScopes: ['read', 'write'],
jwtVerify: {
clockTolerance: 60, // 允许 60 秒的时钟偏差
},
remoteJwtSet: {
timeoutDuration: 10 * 1000, // 远程 JWT 集合获取超时时间为 10 秒
},
});
使用自定义校验配置 Bearer 认证 (Authentication)
如果你的 OAuth / OIDC 提供商不签发 JWT,或者你想实现自己的授权 (Authorization) 逻辑,MCP Auth 允许你创建自定义校验函数:
由于 Bearer 认证 (Authentication) 中间件会根据发行者 (Issuer)(iss
)、受众 (Audience)(aud
)和所需权限 (Scopes)(scope
)与给定的校验结果进行检查,因此你无需在自定义校验函数中实现这些检查。你只需专注于校验令牌的有效性(如签名、过期等)并返回认证 (Authentication) 信息对象即可。
- Python
- Node.js
from mcpauth.exceptions import MCPAuthJwtVerificationException, MCPAuthJwtVerificationExceptionCode
from mcpauth.types import AuthInfo
async def custom_verification(token: str) -> AuthInfo:
# 在这里实现你的自定义校验逻辑
info = await verify_token(token)
if not info:
raise MCPAuthJwtVerificationException(
MCPAuthJwtVerificationExceptionCode.JWT_VERIFICATION_FAILED
)
return info # 返回认证 (Authentication) 信息对象
bearer_auth = mcp_auth.bearer_auth_middleware(
custom_verification,
required_scopes=["read", "write"]
)
const bearerAuth = mcpAuth.bearerAuth(
async (token) => {
// 在这里实现你的自定义校验逻辑
const info = await verifyToken(token);
if (!info) {
throw new MCPAuthJwtVerificationError('jwt_verification_failed');
}
return info; // 返回认证 (Authentication) 信息对象
},
{ requiredScopes: ['read', 'write'] }
);
在 MCP 服务器中应用 Bearer 认证 (Authentication)
要用 Bearer 认证 (Authentication) 保护你的 MCP 服务器,你需要将 Bearer 认证 (Authentication) 中间件应用到 MCP 服务器实例上。
- Python
- Node.js
bearer_auth = mcp_auth.bearer_auth_middleware("jwt", required_scopes=["read", "write"])
app = Starlette(
routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)
const app = express();
app.use(mcpAuth.bearerAuth('jwt', { requiredScopes: ['read', 'write'] }));
这样可以确保所有传入请求都根据配置的 Bearer 认证 (Authentication) 设置进行认证 (Authentication) 和授权 (Authorization),并且认证 (Authentication) 信息会在请求上下文中可用。
你可以在 MCP 服务器实现中访问这些信息:
- Python
- Node.js
@mcp.tool()
async def whoami() -> dict:
# `mcp_auth.auth_info` 是当前请求的上下文对象
auth_info = mcp_auth.auth_info
print(f"Authenticated user: {auth_info.subject}")
return {"subject": auth_info.subject}
// `authInfo` 会从 `req.auth` 对象中传递过来
server.tool('whoami', ({ authInfo }) => {
console.log(`Authenticated user: ${authInfo.subject}`);
return { subject: authInfo.subject };
});