使用灵活的身份验证模式保护您的 FastMCP 服务器,从简单的 API 密钥到与外部身份提供商的完整 OAuth 2.1 集成均可实现。

MCP 中的身份验证面临着与传统 Web 应用程序不同的独特挑战。MCP 客户端需要自动发现身份验证要求、在无需用户干预的情况下协商 OAuth 流程,并且能在不同的身份提供商之间无缝运行。FastMCP 通过提供与 MCP 协议相集成的身份验证模式来应对这些挑战,同时保持了实现和部署的简便性。

身份验证仅适用于 FastMCP 基于 HTTP 的传输方式(http 和 sse)。STDIO 传输方式从其本地执行环境继承安全性。

在 MCP 中,身份验证正在迅速发展。相关规范和最佳实践的变化很快。FastMCP 旨在提供稳定、安全的模式,这些模式能适应这些变化,同时保持你的代码简洁且易于维护。

一、MCP 认证挑战

传统的网络认证假设存在一个使用浏览器的人类用户,该用户能够与登录表单和同意屏幕进行交互。MCP 客户端通常是自动化系统,它们需要在没有人工干预的情况下进行认证。这就产生了几个独特的需求:

  • 自动发现:MCP 客户端必须通过检查服务器元数据来发现认证要求,而不是遇到登录重定向。
  • 程序化 OAuth:OAuth 流程必须在无需人工干预的情况下运行,依赖预先配置的凭证或动态客户端注册。
  • 令牌管理:客户端需要在多个 MCP 服务器间自动获取、刷新和管理令牌。
  • 协议集成:认证必须与 MCP 的传输机制和错误处理无缝集成。

这些挑战意味着并非所有的身份验证方法都能与 MCP 很好地配合。根据服务器承担的身份验证责任级别,切实可行的模式可分为三类。

1.1 认证责任

认证责任存在于一个范围之内。你的 MCP 服务器可以验证在其他地方创建的令牌,与外部身份提供商进行协调,或者在内部处理完整的认证生命周期。每种方法在简便性、安全性和控制性之间都存在不同的权衡。

令牌验证

您的服务器会验证令牌,但将令牌的创建工作委托给外部系统。这种方法将您的 MCP 服务器视为纯粹的资源服务器,它信任由已知发行者签名的令牌。

当您已经拥有能够发行像 JWT 之类的结构化令牌的身份验证基础设施时,令牌验证会很好地发挥作用。您现有的 API 网关、微服务平台或企业单点登录系统成为用户身份的权威来源,而您的 MCP 服务器则专注于其核心功能。

关键要点在于,令牌验证将身份验证(证明您是谁)与授权(确定您能做什么)分离开来。您的 MCP 服务器以签名令牌的形式接收身份证明,并根据该令牌中的声明做出访问决策。

这种模式在微服务架构中表现出色,在这种架构中,多个服务需要验证相同的令牌,或者当将 MCP 服务器集成到已经处理用户身份验证的现有系统中时也是如此。

外部身份提供商

您的服务器与已建立的身份提供商协作,为 MCP 客户端打造无缝的身份验证体验。这种方法利用 OAuth 2.0 和 OpenID Connect 协议来委托用户身份验证,同时保持对授权决策的控制。

外部身份提供商负责处理身份验证的复杂环节:用户凭证验证、多因素认证、账户恢复以及安全监控。您的 MCP 服务器从这些可信提供商处接收令牌,并使用提供商的公钥对其进行验证。

MCP 协议对动态客户端注册的支持让这种模式尤为强大。MCP 客户端能够自动发现您的身份验证要求,并在无需手动配置的情况下向您的身份提供商注册自己。

对于需要企业级身份验证功能但又不想从零开始构建这些复杂功能的生产应用程序而言,这种方法最为适用。它能很好地在多个应用程序间扩展,并提供一致的用户体验。

完整的 OAuth 实现

您的服务器实现了一个完整的 OAuth 2.0 授权服务器,负责从用户凭证验证到令牌生命周期管理的所有工作。这种方法以显著的复杂性为代价提供了最大程度的控制权。

完整的 OAuth 实现意味着要构建用于登录和授权的用户界面,实现安全的凭证存储,管理令牌生命周期,并持续进行安全更新。其复杂性不仅体现在初始实现阶段,还包括威胁监控、合规要求以及跟上不断发展的安全最佳实践。

只有当您需要对认证过程进行完全控制、在隔离环境中运行,或者有外部提供商无法满足的特殊要求时,这种模式才有意义。

1.2 TokenVerifier

令牌验证适用于身份验证职责分布在多个系统中的场景。您的 MCP 服务器会接收包含身份和授权信息的结构化令牌,验证其真实性,并根据令牌内容做出访问控制决策。

这种模式在微服务架构中自然形成,在该架构中,中央身份验证服务会颁发令牌,供多个下游服务独立验证。当将 MCP 服务器集成到已建立基于令牌的身份验证机制的现有系统中时,这种模式也能很好地发挥作用。

认证模型

在 OAuth 术语中,令牌验证将您的 MCP 服务器视为资源服务器。核心思路是,令牌验证和令牌颁发是相互独立的事项,可由不同的系统处理。

  • 令牌颁发:另一个系统(API 网关、认证服务或身份提供商)负责用户认证,并创建包含身份和权限信息的签名令牌。
  • 令牌验证:您的 MCP 服务器接收这些令牌,使用加密签名验证其真实性,并从其声明中提取授权信息。
  • 访问控制:您的服务器根据令牌内容,确定客户端可以访问哪些资源、工具和提示。

这种分离使您的 MCP 服务器能够专注于其核心功能,同时利用现有的认证基础设施。令牌充当了随每个请求一起传输的便携式身份证明。

挑战

MCP 环境中的挑战在于,客户端在发出请求前需要获取有效的令牌,但 MCP 协议没有为令牌端点提供内置的发现机制。客户端必须通过单独的渠道或预先配置来获取令牌。

JWT 令牌验证
JSON Web 令牌(JWT)是现代应用程序中最常见的令牌格式。FastMCP 的 JWTVerifier 使用行业标准的加密技术和声明验证来验证 JWT。

验证流程

客户端 → 1. 向 JWKS 服务请求 JWT → 2. JWKS 服务用私钥签名返回 JWT → 3. 客户端携带 JWT 访问 MCP 工具 → 4. MCP 服务从 JWKS 端点获取公钥 → 5. 验证 JWT 有效性 → 6. 允许访问工具

示例代码:
示例代码有3个文件,我放到了gitcode项目中,地址:

https://gitcode.com/drx000/FastMCP2

此示例配置了针对 JWT 签发者的令牌验证。JWTVerifier 将从 JWKS 端点获取公钥,并根据这些密钥验证传入的令牌。只有具有正确签发者和受众声明的令牌才会被接受。

当您同时控制令牌签发者和您的 MCP 服务器,或者与现有的基于 JWT 的基础设施集成时,TokenVerifier 能很好地发挥作用。


对称密钥验证(HMAC)

  • 对称密钥验证使用共享密钥进行签名和验证,这使其非常适合内部微服务和可信环境,在这些环境中,相同的密钥可以安全地分发给令牌发行者和验证者。

  • 这种方法通常用于微服务架构中,即服务共享一个密钥时,或者当您的身份验证服务和 MCP 服务器都由同一组织管理时。当共享密钥得到妥善管理时,HMAC 算法(HS256、HS384、HS512)可提供强大的安全性。

此时,public_key的意义是共享目标,不是公钥

from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier

# Use a shared secret for symmetric key verification
verifier = JWTVerifier(
    public_key="your-shared-secret-key-minimum-32-chars",  # Despite the name, this accepts symmetric secrets
    issuer="internal-auth-service",
    audience="mcp-internal-api",
    algorithm="HS256"  # or HS384, HS512 for stronger security
)

mcp = FastMCP(name="Internal API", auth=verifier)

示例代码:

示例代码有3个文件,我放到了gitcode项目中,地址:

https://gitcode.com/drx000/FastMCP2

静态公钥验证
当您拥有固定的 RSA 或 ECDSA 签名密钥且不需要自动密钥轮换时,静态公钥验证就会发挥作用。这种方法主要适用于开发环境或没有 JWKS 端点的受控部署场景。

from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier

# Use a static public key for token verification
public_key_pem = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----"""

verifier = JWTVerifier(
    public_key=public_key_pem,
    issuer="https://auth.yourcompany.com",
    audience="mcp-production-api"
)

mcp = FastMCP(name="Protected API", auth=verifier)

理解不透明令牌

不透明令牌在验证模型上与 JWT 有着根本区别。JWT 携带可在本地验证的签名声明,而不透明令牌则需要通过网络调用发行它的授权服务器来进行验证。授权服务器会维护令牌状态,并且能够立即撤销令牌,这为敏感操作提供了更强的安全保障。
这种方法以性能(每次验证时的网络延迟)为代价换取了安全性和灵活性。授权服务器可以立即撤销不透明令牌、实施复杂的授权逻辑,并维护详细的令牌使用审计日志。许多企业级 OAuth 提供商出于这些安全优势,默认使用不透明令牌。

令牌introspection 协议
该协议定义了一个 introspection 端点,资源服务器可在此端点使用客户端凭证进行身份验证,并接收令牌元数据,包括活动状态、范围、过期时间和主体身份。
FastMCP 通过 IntrospectionTokenVerifier 类实现了该协议,根据规范处理身份验证、请求格式化和响应解析。

from fastmcp import FastMCP
from fastmcp.server.auth.providers.introspection import IntrospectionTokenVerifier

# Configure introspection with your OAuth provider
verifier = IntrospectionTokenVerifier(
    introspection_url="https://auth.yourcompany.com/oauth/introspect",
    client_id="mcp-resource-server",
    client_secret="your-client-secret",
    required_scopes=["api:read", "api:write"]
)

mcp = FastMCP(name="Protected API", auth=verifier)

验证者使用你的客户端凭据通过 HTTP 基本认证向 introspection 端点进行身份验证。当带有承载令牌的请求到达时,FastMCP 会查询 introspection 端点,以确定该令牌是否处于活动状态且具有足够的权限范围。

静态令牌验证
静态令牌验证通过接受带有相关声明的预定义令牌,支持快速开发。这种方法消除了开发和测试期间对令牌生成基础设施的需求。

from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import StaticTokenVerifier

# Define development tokens and their associated claims
verifier = StaticTokenVerifier(
    tokens={
        "dev-alice-token": {
            "client_id": "alice@company.com",
            "scopes": ["read:data", "write:data", "admin:users"]
        },
        "dev-guest-token": {
            "client_id": "guest-user",
            "scopes": ["read:data"]
        }
    },
    required_scopes=["read:data"]
)

mcp = FastMCP(name="Development Server", auth=verifier)

客户端现在可以使用 “Authorization: Bearer dev-alice-token” 头部进行身份验证。服务器会识别该令牌并加载相关声明,以用于授权决策。这种方法支持无需外部依赖即可立即开展开发工作。

DebugTokenVerifier
DebugTokenVerifier 为测试以及标准令牌验证不适用的特殊情况提供了最大的灵活性。它将验证工作委托给用户提供的可调用对象,这使其在原型设计、测试场景中,或者在处理没有内省端点的不透明令牌时非常有用。

from fastmcp import FastMCP
from fastmcp.server.auth.providers.debug import DebugTokenVerifier

# Accept all tokens (useful for rapid development)
verifier = DebugTokenVerifier()

mcp = FastMCP(name="Development Server", auth=verifier)

默认情况下,DebugTokenVerifier 接受任何非空令牌为有效令牌。这消除了早期开发过程中的身份验证障碍,让你能够在添加安全性之前专注于核心功能。
如需更可控的测试,请提供自定义验证逻辑:

from fastmcp.server.auth.providers.debug import DebugTokenVerifier

# Synchronous validation - check token prefix
verifier = DebugTokenVerifier(
    validate=lambda token: token.startswith("dev-"),
    client_id="development-client",
    scopes=["read", "write"]
)

mcp = FastMCP(name="Development Server", auth=verifier)

验证可调用对象也可以是异步的,从而支持数据库查询或外部服务调用

from fastmcp.server.auth.providers.debug import DebugTokenVerifier

# Asynchronous validation - check against cache
async def validate_token(token: str) -> bool:
    # Check if token exists in Redis, database, etc.
    return await redis.exists(f"valid_tokens:{token}")

verifier = DebugTokenVerifier(
    validate=validate_token,
    client_id="api-client",
    scopes=["api:access"]
)

mcp = FastMCP(name="Custom API", auth=verifier)

测试Token生成

from fastmcp.server.auth.providers.jwt import JWTVerifier, RSAKeyPair

# Generate a key pair for testing
key_pair = RSAKeyPair.generate()

# Configure your server with the public key
verifier = JWTVerifier(
    public_key=key_pair.public_key,
    issuer="https://test.yourcompany.com",
    audience="test-mcp-server"
)

# Generate a test token using the private key
test_token = key_pair.create_token(
    subject="test-user-123",
    issuer="https://test.yourcompany.com", 
    audience="test-mcp-server",
    scopes=["read", "write", "admin"]
)

print(f"Test token: {test_token}")

RemoteAuthProvider

RemoteAuthProvider 支持通过支持动态客户端注册(DCR)的身份提供商进行身份验证,例如 Descope 和 WorkOS AuthKit。借助 DCR,MCP 客户端可以自动在身份提供商处注册并获取凭据,无需任何手动配置。

此类将令牌验证与 OAuth 发现元数据相结合。它通过添加 OAuth 2.0 受保护资源端点来扩展 TokenVerifier 的功能,这些端点会公布您的身份验证要求。MCP 客户端会检查这些端点,以了解您信任哪些身份提供商以及如何获取有效的令牌。

关键要求是您的身份提供商必须支持 DCR—— 即客户端能够动态注册并获取凭据的能力。这正是实现 MCP 所需的无缝、自动化身份验证流程的基础。

例如,内置的 AuthKitProvider 使用 WorkOS AuthKit,后者完全支持 DCR:

from fastmcp import FastMCP
from fastmcp.server.auth.providers.workos import AuthKitProvider

auth = AuthKitProvider(
    authkit_domain="https://your-project.authkit.app",
    base_url="https://your-fastmcp-server.com"
)

mcp = FastMCP(name="Enterprise Server", auth=auth)

本示例使用 WorkOS AuthKit 作为外部身份提供商。AuthKitProvider 会自动配置针对 WorkOS 的令牌验证,并提供 MCP 客户端自动认证所需的 OAuth 元数据。

当你的身份提供商支持动态客户端注册(DCR)时,RemoteAuthProvider 非常适合生产应用。这实现了完全自动化的认证,无需手动配置客户端。

OAuthProxy

OAuthProxy 支持与不支持动态客户端注册(DCR)的 OAuth 提供商进行身份验证,例如 GitHub、Google、Azure、AWS 以及大多数传统的企业身份系统。

当身份提供商需要手动注册应用程序和固定凭证时,OAuthProxy 能填补这一空白。它向 MCP 客户端提供符合 DCR 标准的接口(接受任何注册请求),同时将你预先注册的凭证用于上游提供商。该代理处理回调转发的复杂性,使动态客户端回调能够与需要固定重定向 URI 的提供商配合使用。

此类解决了 MCP 对动态注册的预期与传统 OAuth 提供商对手动应用程序注册的要求之间的根本不兼容性。

例如,内置的 GitHubProvider 扩展了 OAuthProxy,以适配 GitHub 的 OAuth 系统:

from fastmcp import FastMCP
from fastmcp.server.auth.providers.github import GitHubProvider

auth = GitHubProvider(
    client_id="Ov23li...",  # Your GitHub OAuth App ID
    client_secret="abc123...",  # Your GitHub OAuth App Secret
    base_url="https://your-server.com"
)

mcp = FastMCP(name="GitHub-Protected Server", auth=auth)

此示例使用了 GitHub 提供程序,该程序通过特定于 GitHub 的令牌验证来扩展 OAuthProxy。该代理处理完整的 OAuth 流程,同时使 GitHub 的非 DCR 身份验证能够与 MCP 客户端无缝协作。

当与不支持 DCR 的 OAuth 提供程序集成时,OAuthProxy 至关重要。这包括大多数知名的提供程序,如 GitHub、谷歌和 Azure,它们需要通过各自的开发者控制台进行手动应用注册。

OAuthProvider

OAuthProvider 在您的 MCP 服务器中实现了一个完整的 OAuth 2.0 授权服务器。此类处理从用户凭据验证到令牌管理的完整身份验证生命周期。

该实现提供了所有必需的 OAuth 端点,包括授权端点、令牌端点和发现端点。它在与您的用户存储和身份验证逻辑集成的同时,管理客户端注册、用户同意和令牌生命周期。

from fastmcp import FastMCP
from fastmcp.server.auth.providers.oauth import MyOAuthProvider

auth = MyOAuthProvider(
    user_store=your_user_database,
    client_store=your_client_registry,
    # Additional configuration...
)

mcp = FastMCP(name="Auth Server", auth=auth)

此示例展示了自定义 OAuth 提供商的基本结构。实际实现需要在用户管理、客户端注册和安全策略方面进行大量额外配置。

只有当您有外部提供商无法满足的特定要求,并且具备安全实施 OAuth 的专业知识时,才应使用 OAuthProvider。

配置方法

FastMCP 既支持编程式配置以实现最大灵活性,也支持基于环境的配置以简化部署。

程序化配置

程序化配置提供了对身份验证设置的完全控制,并允许实现复杂的初始化逻辑。这种方法在开发过程中以及需要根据运行时条件自定义身份验证行为时非常有效。

身份验证提供程序在代码中直接实例化,并附带其所需的参数。这使得依赖关系更加明确,并允许你的集成开发环境(IDE)提供有用的自动补全和类型检查功能。

环境配置

基于环境的配置将身份验证设置与应用程序代码分离,使同一个代码库无需修改就能在不同的部署环境中运行。

当未提供明确的身份验证参数时,FastMCP 会自动从环境变量中检测身份验证配置。该配置系统支持所有身份验证提供商及其各种选项。

提供商配置

身份验证提供程序是通过指定提供程序类的完整模块路径来配置的:

FASTMCP_SERVER_AUTH string

身份验证提供程序类的完整模块路径。示例:

  • fastmcp.server.auth.providers.github.GitHubProvider - GitHub OAuth(GitHub 开放授权)
  • fastmcp.server.auth.providers.google.GoogleProvider - Google OAuth(谷歌开放授权)
  • fastmcp.server.auth.providers.jwt.JWTVerifier - JWT 令牌验证
  • fastmcp.server.auth.providers.workos.WorkOSProvider - WorkOS OAuth(WorkOS 开放授权)
  • fastmcp.server.auth.providers.workos.AuthKitProvider - WorkOS AuthKit(WorkOS 身份验证工具包)
  • mycompany.auth.CustomProvider - 您的自定义提供程序类

使用 GitHub 或 Google 等提供商时,你需要设置特定于提供商的环境变量:

# GitHub OAuth
export FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.github.GitHubProvider
export FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID="Ov23li..."
export FASTMCP_SERVER_AUTH_GITHUB_CLIENT_SECRET="github_pat_..."

# Google OAuth
export FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.google.GoogleProvider
export FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_ID="123456.apps.googleusercontent.com"
export FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_SECRET="GOCSPX-..."

特定提供商配置

每个提供商都有通过环境变量设置的自身配置选项:

# JWT Token Verification
export FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.jwt.JWTVerifier
export FASTMCP_SERVER_AUTH_JWT_JWKS_URI="https://auth.example.com/jwks"
export FASTMCP_SERVER_AUTH_JWT_ISSUER="https://auth.example.com"
export FASTMCP_SERVER_AUTH_JWT_AUDIENCE="mcp-server"

# Custom Provider
export FASTMCP_SERVER_AUTH=mycompany.auth.CustomProvider
# Plus any environment variables your custom provider expects

设置好这些环境变量后,创建一个经过身份验证的 FastMCP 服务器不需要额外的配置:

from fastmcp import FastMCP

# Authentication automatically configured from environment
mcp = FastMCP(name="My Server")

这种方法简化了部署流程,并遵循十二因素应用原则进行配置管理。

选择你的实施方案

您选择的身份验证方法取决于您现有的基础设施、安全要求和运营限制。

对于不支持动态客户端注册(DCR)的 OAuth 提供商(GitHub、谷歌、Azure、AWS 以及大多数企业系统),请使用 OAuth 代理。这些提供商要求通过其开发者控制台手动注册应用程序。OAuth 代理通过向 MCP 客户端提供符合 DCR 标准的接口,同时使用您与提供商的固定凭据,来填补这一空白。该代理的回调转发模式使动态客户端端口能够与需要固定重定向 URI 的提供商配合使用。

对于支持 DCR 的身份提供商(Descope、WorkOS AuthKit、现代身份验证平台),请使用 RemoteAuthProvider。这些提供商允许客户端动态注册并获取凭据,无需手动配置。这实现了 MCP 所设计的全自动身份验证流程,提供最佳的用户体验和最简单的实施方式。

当您已经拥有能颁发结构化令牌的身份验证基础设施时,令牌验证会很有效。如果您的组织已经在使用基于 JWT 的系统、API 网关或能够生成令牌的企业单点登录(SSO),这种方法可以无缝集成,同时让您的 MCP 服务器专注于其核心功能。其简便性源于利用在身份验证基础设施方面的现有投入。

除非有外部提供商无法满足的令人信服的理由,否则应避免完全的 OAuth 实施。与外界隔离的环境、特殊的合规要求或独特的组织限制可能会证明这种方法的合理性,但它需要大量的安全专业知识和持续的维护投入。其复杂性远远超出了初始实施阶段,还包括威胁监控、安全更新以及跟上不断演变的攻击向量。

随着您的需求不断发展,FastMCP 的架构支持在这些方法之间进行迁移。您最初可以与现有的令牌系统集成,随着应用程序的扩展迁移到外部身份提供商,或者当您的需求超出标准模式时,实施自定义解决方案。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐