메인 콘텐츠로 건너뛰기

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) 검증 예시입니다:

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)])]
)

위 예시에서 JWT에 readwrite 스코프 (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 미들웨어에 지정할 수 있습니다:

bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt",
    audience="https://api.example.com/mcp",  # JWT의 예상 대상 (Audience)
    required_scopes=["read", "write"]
)

위 예시에서는 MCP Auth가 JWT의 aud 클레임 (Claim)과 필요한 스코프 (Scope) 둘 다 검증합니다.

JWT 검증에 커스텀 옵션 제공하기

기본 JWT 검증 라이브러리에 커스텀 옵션을 제공할 수도 있습니다:

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초의 여유로 클럭 스큐를 줄임
)

커스텀 검증으로 Bearer 인증 (Authentication) 구성하기

OAuth / OIDC 제공자가 JWT를 발급하지 않거나, 직접 인가 (Authorization) 로직을 구현하고 싶다면, MCP Auth에서 커스텀 검증 함수를 만들 수 있습니다:

정보

Bearer 인증 (Authentication) 미들웨어는 발급자 (iss), 대상 (aud), 그리고 필요한 스코프 (scope)를 주어진 검증 결과와 비교하므로, 커스텀 검증 함수에서 이 검증들을 직접 구현할 필요가 없습니다. 토큰의 유효성 (예: 서명, 만료 등) 검증과 인증 (Authentication) 정보 객체 반환에 집중하면 됩니다.

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"]
)

MCP 서버에 Bearer 인증 (Authentication) 적용하기

MCP 서버를 Bearer 인증 (Authentication)으로 보호하려면, MCP 서버 인스턴스에 Bearer 인증 (Authentication) 미들웨어를 적용해야 합니다.

bearer_auth = mcp_auth.bearer_auth_middleware("jwt", required_scopes=["read", "write"])
app = Starlette(
    routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)

이렇게 하면 모든 들어오는 요청이 구성된 Bearer 인증 (Authentication) 설정에 따라 인증 (Authentication) 및 인가 (Authorization)되고, 인증 (Authentication) 정보가 요청 컨텍스트에서 사용할 수 있게 됩니다.

이후 MCP 서버 구현에서 해당 정보를 사용할 수 있습니다:

@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}