メインコンテンツにスキップ

ID-JAGによるエンタープライズ管理認可

本ガイドでは、企業向けのMCP認可仕様の拡張であるEnterprise-Managed Authorizationについて説明します。エンタープライズIDプロバイダー(IdP)が従業員の使用可能なMCPサーバーを決定し、MCPクライアントは各サーバーでブラウザでのサインインなしにトークンを取得します。Casdoorはどちらの役割も果たせます。

  • MCPサーバーの認可サーバーとして: Casdoorは、組織が信頼するエンタープライズIdPのID-JAGを受け入れます。
  • エンタープライズ IdP: Casdoor は、その認可サーバーが信頼する MCP サーバーに対して ID-JAG を発行します。

学習目標​

  • フローと ID-JAG の概要を理解する。
  • Casdoor の組織で、エンタープライズ IdP の ID-JAG を信頼させる。
  • Casdoor から ID-JAG を発行する。

必要なもの​

  • Casdoor 管理コンソールへのグローバル管理者アクセス権
  • この拡張機能をサポートする MCP クライアント(例:Okta Cross App Access を使用した Claude Team または Enterprise)

仕組み​

ID-JAG (Identity Assertion JWT Authorization Grant) は、IdP が署名する短命な JWT です。これは「このユーザーはこの認可サーバーでこのクライアントを使用できます」と示します。draft-ietf-oauth-identity-assertion-authz-grant で定義されており、MCP 拡張機能 io.modelcontextprotocol/enterprise-managed-authorization はこれに基づいています。詳細は Enterprise-Managed Authorization を参照してください。

ユーザーは Casdoor のサインインページを見ることはありません。IdP がユーザーを停止した場合(例えば退職後など)、クライアントは新しい ID-JAG も新しいアクセストークンも取得できません。

Casdoor で ID-JAG を受け入れる​

IdP を信頼する​

  1. Casdoor 管理コンソールで、User Management > Organizations に移動し、ユーザーの組織(例:acme)を開きます。

  2. オプションで Use organization issuer を有効にすると、組織独自の発行者 https://your-casdoor.com/orgs/acme が設定されます。有効にしない場合、発行者はグローバルの https://your-casdoor.com になります。

  3. Trusted ID-JAG issuers の下に、行を追加します:

    ColumnValue
    IssuerID-JAG の iss(例:https://acme.okta.com)
    JWKS URLIdP のキーセット。空欄の場合、Casdoor は <issuer>/.well-known/openid-configuration から jwks_uri を読み取ります
    User組織内でユーザーを検索する方法: {email}(デフォルト)は email クレーム、 {sub} は sub クレーム、その他の {claim} は該当するクレームを使用します。Casdoor はこれをユーザー名、メールアドレス、電話番号、ID と照合します
  4. 組織を保存します。信頼できる発行者を変更できるのはグローバル管理者のみです。

IdP では、Casdoor に対して、ID-JAG のオーディエンスとして組織の発行者を、リソースとして MCP サーバーの URL を指定します。MCP gateway の背後にあるサーバーの場合、これは https://your-casdoor.com/api/server/acme/<server-name> です。

クライアントによるグラントの使用​

クライアントは JWT ベアラートグラント(urn:ietf:params:oauth:grant-type:jwt-bearer)を使用してトークンエンドポイントで ID-JAG を交換するため、そのアプリケーションではこのグラントタイプが許可されている必要があります:

  • Claude: クライアント ID メタデータドキュメント https://claude.ai/oauth/mcp-oauth-client-metadata にグラントがリストされています。Casdoor がこのドキュメントを受け入れられるように、組織で Enable dynamic client registration を有効にしてください。詳細は Connect Claude を参照してください。
  • 自分で作成したアプリケーション: Grant types に JWT Bearer を追加します。

クライアントが送信する内容​

curl -X POST https://your-casdoor.com/api/login/oauth/access_token \
-d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
-d client_id=<client-id> \
-d client_secret=<client-secret> \
-d assertion=<ID-JAG>

Casdoor は、ID-JAG の resource をオーディエンスとするアクセストークンを返答します:

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 604800,
"scope": "openid profile"
}

Casdoor によるチェック項目​

チェックルール
タイプJWT ヘッダーに typ: oauth-id-jag+jwt が含まれています。他のアサーションは通常の JWT bearer grant を通ります
クライアントコンフィデンシャルクライアントは、クライアントシークレットまたは private_key_jwt を使用して認証します。Claude などのクライアント ID メタデータドキュメントを使用するパブリッククライアントはシークレットを持たず、client_id のみを送信します
オーディエンスaud は、独自の発行者を持つ組織の発行者、またはクライアントのアプリケーションに対応する組織を表すグローバル発行者です
発行者と署名iss はその組織の信頼できる発行者であり、ヘッダーの kid に対応する JWKS 内のキーによって署名が検証されます
有効期限exp と iat が存在し、有効です。1 分の猶予があります
クライアントバインドclient_id は、それを使用するクライアントのクライアント ID と一致します
単一使用Casdoor は、各発行者からの jti を一度だけ受け入れます
ユーザーUser フィールドを通じて検索されたユーザーが組織内に存在し、禁止されておらず、クライアントのアプリケーションにサインインできる必要があります
スコープリクエスト内の scope は、ID-JAG の scope のサブセットである必要があります。指定がない場合、トークンは ID-JAG のスコープを取得します
リソースresource が存在する場合、それはアクセストークンのオーディエンスになります

自己登録したクライアント(DCR)またはクライアント ID メタデータドキュメントを使用するクライアントは、ID-JAG を使用する場合のみ JWT ベアラートグラントを利用できます。

エラー​

ErrorCause
invalid_clientコンフィデンシャルクライアントが認証されませんでした
invalid_grantID-JAG はいずれかのチェックに失敗しました:オーディエンスエラー、信頼できない発行者、不正な署名、期限切れ、別のクライアント宛、既に使用済み、またはユーザーが存在しない
invalid_scopeリクエストが ID-JAG で許可されていないスコープを要求しています
invalid_targetID-JAG の resource が絶対 URI ではありません
unsupported_grant_typeクライアントアプリケーションの grant types に JWT Bearer が含まれていません

認可サーバーメタデータはサポートを通知します: grant_types_supported に urn:ietf:params:oauth:grant-type:jwt-bearer が含まれ、authorization_grant_profiles_supported に urn:ietf:params:oauth:grant-profile:id-jag が含まれます。

Casdoor から ID-JAG を発行する​

Casdoor が企業の IdP である場合、クライアントは Casdoor のトークンエンドポイントでユーザーの ID トークンを ID-JAG と交換するために、トークン交換 (RFC 8693) を使用します:

curl -X POST https://your-casdoor.com/api/login/oauth/access_token \
-d grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
-d client_id=<client-id> \
-d client_secret=<client-secret> \
-d requested_token_type=urn:ietf:params:oauth:token-type:id-jag \
-d subject_token=<ID token of the user> \
-d subject_token_type=urn:ietf:params:oauth:token-type:id_token \
-d audience=https://mcp-as.example.com \
-d resource=https://mcp.example.com/mcp \
-d scope="openid profile"
{
"issued_token_type": "urn:ietf:params:oauth:token-type:id-jag",
"access_token": "eyJ0eXAiOiJvYXV0aC1pZC1qYWcrand0Ii...",
"token_type": "N_A",
"expires_in": 300,
"scope": "openid profile"
}

以下のように設定してください:

  1. クライアントアプリケーションの Grant types に Token Exchange を追加します。
  2. ユーザーの組織の LLM AI > MCP Servers ページで MCP サーバーを登録し、その URL を resource として指定し、それを表す Application を選択します。resource がない場合、Casdoor は audience(クライアント ID またはアプリケーション名)によってアプリケーションを検索します。
  3. ユーザーにアクセス権限を付与します: Resource type を Application に設定し、リソースとしてサーバーのアプリケーションを指定し、Effect を Allow に設定して権限を追加します。Casdoor は Allow 権限が適用されるユーザーにのみ ID-JAG を発行するため、誰も権限が付与されていないアプリケーションは閉じたままになります。

ID-JAG の有効期間は 5 分です。その aud はリクエストの audience であり、client_id はリクエスト元アプリケーションのクライアント ID です。また、ユーザーの email、resource、および scope を保持します。MCP サーバーの認可サーバーは Casdoor の発行元を信頼する必要があり、クライアントはそこで同じクライアント ID(例えば、クライアント ID メタデータドキュメントの URL)を使用する必要があります。

関連項目​