메인 콘텐츠로 건너뛰기

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에 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 미들웨어에 지정할 수 있습니다:

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}