byteforce

CPN 한국어 자습서 · 외부 문서 한국어 미러

MCP 문서 · Tutorials

MCP 인증 이해하기

Understanding Authorization in MCP · 원문: modelcontextprotocol.io/docs/tutorials/security/authorization

아래는 원문을 한국어로 옮긴 미러입니다. 코드·명령은 원문 그대로이며, 가장 최신 정보는 하단 원문 링크에서 확인하세요.

OAuth 2.1을 사용해 민감한 리소스와 작업을 보호하는 MCP 서버 인증 구현 방법

Model Context Protocol(MCP)에서 인증(authorization)은 MCP 서버가 노출하는 민감한 리소스와 작업에 대한 접근을 보호합니다. MCP 서버가 사용자 데이터나 관리 작업을 처리한다면, 인증을 통해 허가된 사용자만 엔드포인트에 접근할 수 있도록 보장합니다.

MCP는 MCP 클라이언트와 MCP 서버 간의 신뢰를 구축하기 위해 표준화된 인증 흐름을 사용합니다. 특정 인증 또는 신원 시스템에 의존하지 않고, OAuth 2.1에서 정의한 관례를 따릅니다. 자세한 내용은 인증 사양을 참고하십시오.

인증을 사용해야 하는 경우

MCP 서버의 인증은 선택 사항이지만, 다음과 같은 경우에 강력히 권장합니다.

팁: 로컬 MCP 서버의 인증

STDIO 전송을 사용하는 MCP 서버의 경우, MCP 서버에 직접 내장된 서드파티 라이브러리에서 제공하는 환경 기반 자격 증명이나 자격 증명을 대신 사용할 수 있습니다. STDIO 기반 MCP 서버는 로컬에서 실행되므로, 브라우저 내 인증 및 인증 흐름에 의존하거나 의존하지 않는 다양한 유연한 자격 증명 획득 방법에 접근할 수 있습니다.

OAuth 흐름은 MCP 서버가 원격으로 호스팅되고 클라이언트가 OAuth를 사용해 사용자가 해당 원격 서버에 접근할 권한이 있음을 확인하는 HTTP 기반 전송을 위해 설계되었습니다.

인증 흐름: 단계별 설명

클라이언트가 보호된 MCP 서버에 연결하려 할 때 발생하는 과정을 단계별로 살펴봅니다.

1단계: 초기 핸드셰이크

MCP 클라이언트가 처음 연결을 시도하면, 서버는 401 Unauthorized로 응답하고 Protected Resource Metadata(PRM) 문서에서 인증 정보를 찾을 수 있는 위치를 클라이언트에 알립니다. 이 문서는 MCP 서버가 호스팅하며, 예측 가능한 경로 패턴을 따르고, WWW-Authenticate 헤더 내 resource_metadata 파라미터로 클라이언트에 제공됩니다.

코드 · 명령
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp",
  resource_metadata="https://your-server.com/.well-known/oauth-protected-resource"

이는 MCP 서버에 인증이 필요하며, 인증 흐름을 시작하는 데 필요한 정보를 어디서 얻을 수 있는지 클라이언트에 알립니다.

2단계: Protected Resource Metadata 탐색

PRM 문서의 URI 포인터를 통해 클라이언트는 메타데이터를 가져와 인증 서버, 지원되는 스코프, 기타 리소스 정보를 파악합니다. 데이터는 일반적으로 다음과 유사한 JSON 형태로 캡슐화됩니다.

코드 · 명령
{
  "resource": "https://your-server.com/mcp",
  "authorization_servers": ["https://auth.your-server.com"],
  "scopes_supported": ["mcp:tools", "mcp:resources"]
}

더 포괄적인 예시는 RFC 9728 Section 3.2에서 확인할 수 있습니다.

3단계: 인증 서버 탐색

다음으로 클라이언트는 인증 서버가 무엇을 할 수 있는지 메타데이터를 가져와 파악합니다. PRM 문서에 여러 인증 서버가 나열된 경우, 클라이언트는 사용할 서버를 선택할 수 있습니다.

인증 서버를 선택한 후, 클라이언트는 표준 메타데이터 URI를 구성하고 OpenID Connect(OIDC) 탐색 또는 OAuth 2.0 인증 서버 메타데이터 엔드포인트에 요청을 보내 인증 흐름을 완료하는 데 필요한 엔드포인트 정보를 포함한 메타데이터 속성을 가져옵니다.

코드 · 명령
{
  "issuer": "https://auth.your-server.com",
  "authorization_endpoint": "https://auth.your-server.com/authorize",
  "token_endpoint": "https://auth.your-server.com/token",
  "registration_endpoint": "https://auth.your-server.com/register"
}

4단계: 클라이언트 등록

메타데이터 확인이 완료되면, 클라이언트는 인증 서버에 등록되었는지 확인해야 합니다. 이는 두 가지 방법으로 할 수 있습니다.

첫 번째로, 클라이언트가 특정 인증 서버에 사전 등록되어 있는 경우, 인증 흐름을 완료하는 데 사용할 클라이언트 등록 정보가 내장되어 있습니다.

두 번째로, 클라이언트는 Dynamic Client Registration(DCR)을 사용해 인증 서버에 동적으로 등록할 수 있습니다. 후자의 방식은 인증 서버가 DCR을 지원해야 합니다. 인증 서버가 DCR을 지원하는 경우, 클라이언트는 registration_endpoint에 다음과 같은 정보를 담은 요청을 보냅니다.

코드 · 명령
{
  "client_name": "My MCP Client",
  "redirect_uris": ["http://localhost:3000/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"]
}

등록이 성공하면, 인증 서버는 클라이언트 등록 정보가 담긴 JSON을 반환합니다.

팁: DCR 또는 사전 등록이 없는 경우

MCP 클라이언트가 DCR을 지원하지 않는 인증 서버를 사용하는 MCP 서버에 연결하고, 클라이언트가 해당 인증 서버에 사전 등록되지 않은 경우, 클라이언트 개발자는 최종 사용자가 클라이언트 정보를 직접 입력할 수 있는 수단을 제공할 책임이 있습니다.

5단계: 사용자 인증

클라이언트는 이제 /authorize 엔드포인트로 브라우저를 열어 사용자가 로그인하고 필요한 권한을 부여할 수 있게 합니다. 인증 서버는 클라이언트가 토큰으로 교환할 인증 코드와 함께 클라이언트로 리디렉션합니다.

코드 · 명령
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "def502...",
  "token_type": "Bearer",
  "expires_in": 3600
}

액세스 토큰은 클라이언트가 MCP 서버에 요청을 인증하는 데 사용합니다. 이 단계는 표준 OAuth 2.1 PKCE 방식 인증 코드 관례를 따릅니다.

6단계: 인증된 요청 보내기

마지막으로, 클라이언트는 Authorization 헤더에 액세스 토큰을 포함해 MCP 서버에 요청을 보낼 수 있습니다.

코드 · 명령
GET /mcp HTTP/1.1
Host: your-server.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

MCP 서버는 토큰을 검증하고, 토큰이 유효하며 필요한 권한을 가지고 있는 경우 요청을 처리합니다.

구현 예시

실용적인 구현을 시작하기 위해 Docker 컨테이너에서 호스팅되는 Keycloak 인증 서버를 사용합니다. Keycloak은 테스트 및 실험을 위해 로컬에 쉽게 배포할 수 있는 오픈 소스 인증 서버입니다.

Docker Desktop을 다운로드하여 설치하십시오. 개발 머신에 Keycloak을 배포하는 데 필요합니다.

Keycloak 설정

터미널 애플리케이션에서 다음 명령을 실행해 Keycloak 컨테이너를 시작합니다.

코드 · 명령
docker run -p 127.0.0.1:8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak start-dev

이 명령은 Keycloak 컨테이너 이미지를 로컬에 다운로드하고 기본 설정을 부트스트랩합니다. 포트 8080에서 실행되며 admin 사용자와 admin 비밀번호를 가집니다.

주의: 프로덕션에서는 사용하지 마십시오

위 설정은 테스트와 실험에는 적합할 수 있지만, 프로덕션에서는 절대 사용하지 마십시오. 신뢰성, 보안, 고가용성이 필요한 시나리오에서 인증 서버를 배포하는 방법은 Keycloak 프로덕션 설정 가이드를 참고하십시오.

브라우저에서 http://localhost:8080으로 Keycloak 인증 서버에 접근할 수 있습니다.

기본 설정으로 실행하면 Keycloak은 Dynamic Client Registration을 포함해 MCP 서버에 필요한 많은 기능을 이미 지원합니다. 다음 OIDC 설정에서 이를 확인할 수 있습니다.

코드 · 명령
http://localhost:8080/realms/master/.well-known/openid-configuration

스코프를 지원하고 호스트(로컬 머신)가 클라이언트를 동적으로 등록할 수 있도록 Keycloak을 추가로 설정해야 합니다. 기본 정책은 익명 동적 클라이언트 등록을 제한합니다.

Keycloak 대시보드에서 Client scopes로 이동해 새 mcp:tools 스코프를 생성합니다. MCP 서버의 모든 도구에 접근하는 데 사용할 스코프입니다.

스코프를 생성한 후, 타입을 Default로 지정하고 Include in token scope 스위치를 활성화하십시오. 이는 토큰 검증에 필요합니다.

이제 Keycloak이 발급하는 토큰에 audience를 설정합니다. 발급된 액세스 토큰에 의도된 목적지를 직접 포함시키는 audience 설정은 중요합니다. 이를 통해 MCP 서버는 수신한 토큰이 다른 API가 아닌 자신을 위해 발급된 것임을 확인할 수 있습니다. 토큰 패스스루(token passthrough) 시나리오를 방지하는 데 핵심적입니다.

mcp:tools 클라이언트 스코프를 열고 Mappers를 클릭한 후 Configure a new mapper를 선택합니다. Audience를 선택합니다.

Nameaudience-config를 입력하고, Included Custom Audiencehttp://localhost:3000을 추가합니다. 이것이 테스트 서버의 URI입니다.

주의: 프로덕션에서는 사용하지 마십시오

위 audience 설정은 테스트를 위한 것입니다. 프로덕션 시나리오에서는 발급되는 토큰의 audience가 적절히 제한되도록 추가 설정이 필요합니다. 특히, audience는 고정 값이 아닌 클라이언트에서 전달된 resource 파라미터를 기반으로 해야 합니다.

ClientsClient registrationTrusted Hosts로 이동합니다. Client URIs Must Match 설정을 비활성화하고 테스트하는 호스트를 추가합니다. 현재 호스트 IP는 Linux 또는 macOS에서 ifconfig 명령으로, Windows에서 ipconfig 명령으로 확인할 수 있습니다. Keycloak 로그에서 Failed to verify remote host : 192.168.215.1과 같은 줄을 통해 추가할 IP 주소를 확인할 수 있습니다. 이 IP 주소가 호스트와 연결되어 있는지 확인하십시오. Docker 설정에 따라 브리지 네트워크일 수 있습니다.

주의: 호스트 확인

Keycloak을 컨테이너에서 실행하는 경우, 컨테이너 로그의 Terminal에서도 호스트 IP를 확인할 수 있습니다.

마지막으로, MCP 서버 자체가 토큰 인트로스펙션(token introspection) 등을 위해 Keycloak과 통신하는 데 사용할 새 클라이언트를 등록해야 합니다.

  1. Clients로 이동합니다.
  2. Create client를 클릭합니다.
  3. 고유한 Client ID를 지정하고 Next를 클릭합니다.
  4. Client authentication을 활성화하고 Next를 클릭합니다.
  5. Save를 클릭합니다.

토큰 인트로스펙션은 토큰을 검증하는 여러 방법 중 하나입니다. 각 언어와 플랫폼에 특화된 독립 라이브러리를 사용해 검증할 수도 있습니다.

클라이언트 세부 정보를 열고 Credentials로 이동해 Client Secret을 기록해 두십시오.

주의: 시크릿 처리

클라이언트 자격 증명을 코드에 직접 포함하지 마십시오. 환경 변수나 비밀 저장을 위한 전문 솔루션을 사용하는 것을 권장합니다.

Keycloak이 설정되면, 인증 흐름이 시작될 때마다 MCP 서버는 다음과 같은 토큰을 받게 됩니다.

코드 · 명령
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1TjcxMGw1WW5MWk13WGZ1VlJKWGtCS3ZZMzZzb3JnRG5scmlyZ2tlTHlzIn0...

디코딩하면 다음과 같이 보입니다.

코드 · 명령
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "5N710l5YnLZMwXfuVRJXkBKvY36sorgDnlrirgkeLys"
}.{
  "exp": 1755540817,
  "iat": 1755540757,
  "auth_time": 1755538888,
  "jti": "onrtac:b34080ff-8404-6867-81be-1231b50593a8",
  "iss": "http://localhost:8080/realms/master",
  "aud": "http://localhost:3000",
  "sub": "33ed6c6b-c6e0-4928-a161-f2f69c7a03b9",
  "typ": "Bearer",
  "azp": "7975a5b6-8b59-4a85-9cba-8faebdab8974",
  "sid": "8f7ec276-358f-4ccc-b313-db08290f376f",
  "scope": "mcp:tools"
}.[Signature]

주의: 포함된 Audience

토큰에 포함된 aud 클레임을 확인하십시오. 현재 테스트 MCP 서버의 URI로 설정되어 있으며, 앞서 설정한 스코프에서 유추됩니다. 구현에서 이를 검증하는 것이 중요합니다.

MCP 서버 설정

이제 로컬에서 실행 중인 Keycloak 인증 서버를 사용하도록 MCP 서버를 설정합니다. 선호하는 프로그래밍 언어에 따라 지원되는 MCP SDK 중 하나를 사용할 수 있습니다.

테스트 목적으로 덧셈과 곱셈 두 가지 도구를 노출하는 매우 간단한 MCP 서버를 만듭니다. 서버는 이 도구에 접근하기 위해 인증을 요구합니다.

TypeScript

완전한 TypeScript 프로젝트는 샘플 레포지터리에서 확인할 수 있습니다.

아래 코드를 실행하기 전에 다음 내용의 .env 파일이 있는지 확인하십시오.

코드 · 명령
# Server host/port
HOST=localhost
PORT=3000

# Auth server location
AUTH_HOST=localhost
AUTH_PORT=8080
AUTH_REALM=master

# Keycloak OAuth client credentials
OAUTH_CLIENT_ID=<YOUR_SERVER_CLIENT_ID>
OAUTH_CLIENT_SECRET=<YOUR_SERVER_CLIENT_SECRET>

OAUTH_CLIENT_IDOAUTH_CLIENT_SECRET은 앞서 생성한 MCP 서버 클라이언트와 연결됩니다.

TypeScript SDK를 사용하여 MCP 서버를 구현하는 방법에 대한 자세한 내용은 TypeScript SDK 문서를 참고하십시오.

Python

완전한 Python 프로젝트는 샘플 레포지터리에서 확인할 수 있습니다.

자세한 내용은 Python SDK 문서를 참고하십시오.

C

완전한 C# 프로젝트는 샘플 레포지터리에서 확인할 수 있습니다.

자세한 내용은 C# SDK 문서를 참고하십시오.

MCP 서버 테스트

테스트 목적으로 Visual Studio Code를 사용합니다. MCP 및 새로운 인증 사양을 지원하는 모든 클라이언트를 사용할 수 있습니다.

Cmd + Shift + P를 누르고 MCP: Add server...를 선택합니다. HTTP를 선택하고 http://localhost:3000을 입력합니다. Visual Studio Code 내에서 사용할 고유한 이름을 지정합니다. mcp.json에 다음과 같은 항목이 표시됩니다.

코드 · 명령
"my-mcp-server-18676652": {
  "url": "http://localhost:3000",
  "type": "http"
}

연결 시 브라우저로 이동해 Visual Studio Code가 mcp:tools 스코프에 접근하는 것에 동의하라는 메시지가 표시됩니다.

동의 후, mcp.json의 서버 항목 바로 위에 도구가 나열됩니다. 채팅 뷰에서 # 기호를 사용해 개별 도구를 호출할 수 있습니다.

일반적인 함정과 회피 방법

공격 벡터, 완화 전략, 구현 모범 사례를 포함한 포괄적인 보안 지침은 보안 모범 사례를 읽어보십시오. 아래에 몇 가지 핵심 문제를 설명합니다.

관련 표준 및 문서

MCP 인증은 다음의 검증된 표준을 기반으로 합니다.

추가 세부 정보는 다음을 참고하십시오.

원문(영어): https://modelcontextprotocol.io/docs/tutorials/security/authorization · 본 문서는 학습용 한국어 번역이며 원본의 권리는 원저작자(Model Context Protocol)에게 있습니다.

원문(영어): https://modelcontextprotocol.io/docs/tutorials/security/authorization