MCP 서버에서 Bearer 인증 (Authentication) 구성하기
MCP Auth는 MCP 서버에서 Bearer 인가 (Authorization)를 구성하는 다양한 방법을 제공합니다:
- JWT (JSON Web Token) 모드: 클레임 (Claim) 검증을 통해 JWT를 검증하는 내장 인가 (Authorization) 방식입니다.
- 커스텀 모드: 직접 인가 (Authorization) 로직을 구현할 수 있습니다.
JWT 모드로 Bearer 인증 (Authentication) 구성하기
OAuth / OIDC 제공자가 인가 (Authorization)를 위해 JWT를 발급한다면, MCP Auth의 내장 JWT 모드를 사용할 수 있습니다. 이 모드는 JWT 서명, 만료, 그리고 지정한 기타 클레임 (Claim)을 검증합니다. 이후 인증 (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
스코프 (Scope)가 필요하다고 지정했습니다. JWT에 이 중 하나라도 포함되어 있지 않으면, 요청은 403 Forbidden 오류로 거부됩니다.
리소스 지표 (Resource indicator) 검증 (RFC 8707)
제공자가 OIDC 기반이거나 Resource Indicator 확장을 지원한다면, audience
옵션을 지정하여 JWT의 aud
(대상 (Audience)) 클레임 (Claim)을 검증할 수 있습니다. 이는 JWT가 MCP 서버를 대상으로 발급된 것임을 보장하는 데 유용합니다.
제공자의 문서를 확인하여 Resource Indicator 확장을 지원하는지, 그리고 어떻게 구성하는지 알아보세요. 일부 제공자는 이 개념을 "audience", "API 리소스", "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)과 필요한 스코프 (Scope) 둘 다 검증합니다.
JWT 검증에 커스텀 옵션 제공하기
기본 JWT 검증 라이브러리에 커스텀 옵션을 제공할 수도 있습니다:
- Python
- Node.js
Python SDK에서는 JWT 검증을 위해 PyJWT를 사용합니다. 다음 옵션을 사용할 수 있습니다:
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에서는 JWT 검증을 위해 jose 라이브러리를 사용합니다. 다음 옵션을 제공할 수 있습니다:
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) 미들웨어는 발급자 (iss
), 대상 (aud
), 그리고 필요한 스코프 (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) 적용하기
MCP 서버를 Bearer 인증 (Authentication)으로 보호하려면, MCP 서버 인스턴스에 Bearer 인증 (Authentication) 미들웨어를 적용해야 합니다.
- 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 };
});