Pular para o conteúdo principal
Versão: 0.2.0-beta.1

Configurar autenticação Bearer no servidor MCP

Com a especificação MCP mais recente, seu servidor MCP atua como um Resource Server (Servidor de Recursos) que valida tokens de acesso para recursos protegidos. O MCP Auth oferece várias formas de configurar a autorização Bearer:

  • Modo JWT (JSON Web Token): Um método de autorização integrado que verifica JWTs com afirmações de reivindicações.
  • Modo personalizado: Permite que você implemente sua própria lógica de autorização.

O middleware de autenticação Bearer agora exige a especificação de qual recurso o endpoint pertence, permitindo a validação adequada do token em relação aos servidores de autorização configurados.

Configurar autenticação Bearer com modo JWT

Se seu provedor OAuth / OIDC emite JWTs para autorização, você pode usar o modo JWT integrado no MCP Auth. Ele verifica a assinatura do JWT, expiração e outras reivindicações que você especificar; em seguida, preenche as informações de autenticação no contexto da requisição para processamento posterior em sua implementação MCP.

Validação de escopo (Scope validation)

Aqui está um exemplo de validação básica de escopo:

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", 
    resource="https://api.example.com",  # Especifique a qual recurso este endpoint pertence
    audience="https://api.example.com",  # Habilite a validação do público para segurança
    required_scopes=["read", "write"] 
)

app = Starlette(
    routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)

No exemplo acima, especificamos que o JWT exige os escopos read e write. Se o JWT não contiver nenhum desses escopos, a requisição será rejeitada com um erro 403 Forbidden.

Validação de público (Audience validation) (RFC 8707)

Para validação segura do token, você deve sempre incluir a validação de público especificando o parâmetro audience. Isso valida a reivindicação aud (público) no JWT para garantir que o token foi emitido especificamente para o recurso do seu servidor MCP.

Audience Validation

O parâmetro audience é obrigatório pela especificação OAuth 2.0 para validação segura do token. No entanto, atualmente é opcional para manter a compatibilidade com servidores de autorização que ainda não suportam identificadores de recurso. Por motivos de segurança, sempre inclua o parâmetro audience quando possível. Versões futuras tornarão a validação de público obrigatória para cumprir totalmente a especificação.

O valor do público geralmente deve corresponder ao seu identificador de recurso:

bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt",
    resource="https://api.example.com",  # Especifique a qual recurso este endpoint pertence
    audience="https://api.example.com",  # Habilite a validação do público para segurança
    required_scopes=["read", "write"]
)

No exemplo acima, o MCP Auth validará tanto a reivindicação aud no JWT quanto os escopos necessários.

Forneça opções personalizadas para a verificação do JWT

Você também pode fornecer opções personalizadas para a biblioteca de verificação JWT subjacente:

No SDK Python, usamos PyJWT para verificação de JWT. Você pode usar as seguintes opções:

  • leeway: Permite uma certa margem ao verificar o tempo de expiração do JWT (em segundos). O padrão é 60 segundos.
bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt",
    resource="https://api.example.com",
    audience="https://api.example.com",
    required_scopes=["read", "write"],
    leeway=10,  # Reduza a diferença de relógio permitindo 10 segundos de margem
)

Configurar autenticação Bearer com verificação personalizada

Se seu provedor OAuth / OIDC não emite JWTs, ou se você deseja implementar sua própria lógica de autorização, o MCP Auth permite criar uma função de verificação personalizada:

info

Como o middleware de autenticação Bearer verificará o emissor (iss), público (aud) e escopos necessários (scope) com o resultado da verificação fornecido, não há necessidade de implementar essas verificações em sua função de verificação personalizada. Você pode focar em verificar a validade do token (por exemplo, assinatura, expiração, etc.) e retornar o objeto de informações de autenticação.

from mcpauth.exceptions import MCPAuthJwtVerificationException, MCPAuthJwtVerificationExceptionCode
from mcpauth.types import AuthInfo

async def custom_verification(token: str) -> AuthInfo:
    # Implemente sua lógica personalizada de verificação aqui
    info = await verify_token(token)
    if not info:
        raise MCPAuthJwtVerificationException(
            MCPAuthJwtVerificationExceptionCode.JWT_VERIFICATION_FAILED
        )
    return info  # Retorne o objeto de informações de autenticação

bearer_auth = mcp_auth.bearer_auth_middleware(
    custom_verification,
    resource="https://api.example.com",
    audience="https://api.example.com",  # Habilite a validação do público para segurança
    required_scopes=["read", "write"]
)

Aplicar autenticação Bearer em seu servidor MCP

Para proteger seu servidor MCP com autenticação Bearer, você precisa aplicar o middleware de autenticação Bearer à sua instância do servidor MCP.

bearer_auth = mcp_auth.bearer_auth_middleware("jwt", 
    resource="https://api.example.com",
    audience="https://api.example.com",  # Habilite a validação do público para segurança
    required_scopes=["read", "write"]
)
app = Starlette(
    routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)

Isso garantirá que todas as requisições recebidas sejam autenticadas e autorizadas de acordo com as configurações Bearer auth, e as informações de autenticação estarão disponíveis no contexto da requisição.

Você pode então acessar as informações em sua implementação do servidor MCP:

@mcp.tool()
async def whoami() -> dict:
    # `mcp_auth.auth_info` é o objeto de contexto para a requisição atual
    auth_info = mcp_auth.auth_info
    print(f"Usuário autenticado: {auth_info.subject}")
    return {"subject": auth_info.subject}