OpenAI の Model Context Protocol (MCP) に対応するアプリケーションでは、認可フローに OAuth 2.1 の Authorization Code + PKCE を実装することが求められます。PKCE は公開クライアントでも安全に認可コードフローを利用するための仕組みで、MCP の「Deep Research」コネクタなどを動作させる上で必須となります。本記事では PKCE の基本的な流れと OAuth 2.0 との違い、/authorize・/token の各エンドポイントでの変更点を解説します。
従来の認可コードフローではクライアントは固定の client_secret を使って自身を認証します。しかしブラウザやモバイルアプリのような公開クライアントでは client_secret を安全に保持できません。PKCE(Proof Key for Code Exchange)では以下の手順によってこの問題を解決します。
-
code_verifier の生成
クライアントは 43 文字以上のランダム文字列を生成しcode_verifierとして保持します。 -
code_challenge の生成
code_verifierを SHA-256 でハッシュし Base64URL エンコードしたものをcode_challengeとします。ハッシュ方式は常にS256を使用します。 -
認可リクエストに code_challenge を送信
/authorizeにcode_challengeとcode_challenge_method=S256を含めてユーザー認証を行います。 -
トークンリクエストで code_verifier を送信
認可コードを受け取った後、/tokenリクエストのボディにcode_verifierをcodeと一緒に送ります。サーバーはcode_verifierから計算したcode_challengeが初回リクエストの値と一致するか検証します。 -
一致すればトークンを発行
code_challengeが一致すれば正規のクライアントとしてアクセストークン(必要ならリフレッシュトークン)を返します。
この仕組みにより攻撃者が認可コードを盗んでも code_verifier を知らなければ /token でトークンを取得できません。
OAuth 2.1 では /authorize リクエストで code_challenge と code_challenge_method=S256 の送信が必須になります。例:
GET /authorize?client_id=CLIENT_ID&
response_type=code&
redirect_uri=CALLBACK_URL&
scope=read%20write&
state=STATE_VALUE&
code_challenge=BASE64URL(SHA256(code_verifier))&
code_challenge_method=S256
state は CSRF 対策のためのランダム値で、リダイレクト時にそのまま返却する必要があります。OAuth 2.0 では code_challenge と code_challenge_method の送信は不要でした。
PKCE フローでは /token へのリクエストに client_secret を含めず、代わりに code_verifier を送信します。
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=CLIENT_ID&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL&
code_verifier=ORIGINAL_CODE_VERIFIER
認可サーバーは code_verifier から code_challenge を再計算して検証します。リクエストヘッダに Basic 認証を付ける必要もありません。
| 変更点 | OAuth 2.0 | OAuth 2.1 |
|---|---|---|
| PKCE | 公開クライアント向けに推奨で必須ではない | すべてのクライアントで必須。code_verifier と code_challenge を必ず利用 |
| Implicit フロー | SPAs 向けに存在しアクセストークンを直接返す | 廃止。SPAs も認可コード+PKCEを利用する |
| Resource Owner Password Grant | ユーザーの ID・パスワードを直接送信してトークン取得が可能 | 廃止。代わりに認可コード+PKCEを使用 |
| リダイレクトURIの一致 | ワイルドカードなど柔軟な一致が可能 | 完全一致が必須。登録済みURIと完全一致しない場合は拒否 |
| トークンの送信方法 | クエリ文字列に含めることも許可 | クエリ文字列での送信は禁止。Authorization: Bearer ヘッダ等で送る |
- MCP 対応アプリケーションでは
/.well-known/oauth-authorization-serverと/.well-known/oauth-protected-resourceにメタデータを公開し、grant_types_supportedにauthorization_code(必要ならclient_credentials)を含める。 -
tools_offeredには MCP の規定に沿って必要なツールのみ(searchやfetchなど)を列挙する。 - 認証されていないアクセスには
401とWWW-Authenticateヘッダを返し、resource_metadataに/.well-known/oauth-protected-resourceの URL を示す。 -
/tokenエンドポイントではclient_secretの代わりにcode_verifierを検証し、アクセストークンを発行する。
OAuth 2.1 ではすべてのクライアントで PKCE が必須となり、OpenAI MCP のような公開クライアントでも安全に認可コードフローを利用できるようになっています。/authorize で code_challenge を送信し、/token で code_verifier を検証するフローを正しく実装することで、MCP コネクタの安全な動作を実現できます。
Source link
コメント