Перейти до основного вмісту

Enterprise-managed authorization з ID-JAG

Цей посібник пояснює Enterprise-Managed Authorization — розширення специфікації авторизації MCP для компаній: корпоративний постачальник ідентичності (IdP) вирішує, які MCP-сервери може використовувати працівник, а клієнт MCP отримує свої токени без входу через браузер на кожному сервері. Casdoor може виконувати будь-яку з цих ролей:

  • Сервер авторизації для MCP-серверів: Casdoor приймає ID-JAG від корпоративного IdP, якому довіряє організація.
  • Корпоративний IdP: Casdoor видає ID-JAG для серверів MCP, авторизаційний сервер яких йому довіряє.

Результати навчання​

  • Зрозумійте процес і що таке ID-JAG.
  • Дозвольте організації Casdoor довіряти ID-JAG корпоративного IdP.
  • Випускайте ID-JAG з Casdoor.

Що потрібно​

  • Глобальний доступ адміністратора до адміністративної консолі Casdoor
  • Клієнт MCP, який підтримує це розширення, наприклад Claude Team або Enterprise з Okta Cross App Access

Як це працює​

ID-JAG (Identity Assertion JWT Authorization Grant) — це короткочасний JWT, підписаний IdP. Він означає: цей користувач може використовувати цього клієнта на цьому авторизаційному сервері. Це визначено у draft-ietf-oauth-identity-assertion-authz-grant, а розширення MCP io.modelcontextprotocol/enterprise-managed-authorization базується на ньому. Див. Enterprise-Managed Authorization.

Користувач ніколи не бачить сторінку входу Casdoor. Коли IdP блокує користувача, наприклад після його звільнення з компанії, клієнт не отримує нового ID-JAG і, відповідно, нового токена доступу.

Прийняття ID-JAG у Casdoor​

Довіра до 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
    IssuerЗначення iss для ID-JAG, наприклад https://acme.okta.com
    JWKS URLНабір ключів IdP. Якщо залишити пустим, Casdoor читає jwks_uri з <issuer>/.well-known/openid-configuration
    UserЯк знайти користувача в організації: {email} (за замовчуванням) використовує твердження email, {sub} — твердження sub, будь-яке {claim} — відповідне твердження. Casdoor зіставляє його з ім'ям користувача, email, телефоном та ID
  4. Збережіть налаштування організації. Лише глобальний адміністратор може змінювати довірені емітенти.

У IdP надайте Casdoor емітент організації як аудиторію (audience) для ID-JAG та URL-адреси серверів MCP як ресурси. Для сервера за MCP gateway це https://your-casdoor.com/api/server/acme/<server-name>.

Дозволимо клієнту використовувати грант​

Клієнт обмінює ID-JAG на ендпоінті токенів із використанням JWT bearer grant (urn:ietf:params:oauth:grant-type:jwt-bearer), тому тип гранту має бути дозволений для його додатка:

  • Claude: Його документ метаданих клієнта https://claude.ai/oauth/mcp-oauth-client-metadata містить цей грант. Увімкніть Enable dynamic client registration для організації, щоб Casdoor приймав цей документ. Див. Connect Claude.
  • Створений вами додаток: Додайте JWT Bearer до його Grant types.

Що надсилає клієнт​

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 відповідає токеном доступу, аудиторія якого збігається з полем resource ID-JAG:

{
"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) не має секрету й надсилає лише client_id
Аудиторіяaud є емітентом організації з власним емітентом або глобальним емітентом, який представляє організацію додатка клієнта
Емітент і підписiss є довіреним емітентом цієї організації, а підпис перевіряється ключем із kid із заголовка в його JWKS
Термін діїexp і iat присутні та дійсні, з похибкою в одну хвилину
Прив'язка до клієнтаclient_id збігається з ID клієнта, який здійснює обмін
Одноразове використанняCasdoor приймає кожен jti від конкретного емітента лише один раз
КористувачКористувач, знайдений через поле User, існує в організації, не заблокований і має право входити до додатка клієнта
Обсяг (Scope)scope у запиті має бути підмножиною scope ID-JAG. Якщо він відсутній, токен отримує обсяг із ID-JAG
Ресурсresource, якщо присутній, стає аудиторією токена доступу

Клієнт, який зареєструвався самостійно (DCR) або використовує документ метаданих клієнта, може використовувати JWT bearer grant лише з ID-JAG.

Помилки​

ErrorCause
invalid_clientКонфіденційний клієнт не пройшов автентифікацію
invalid_grantID-JAG не пройшов одну з перевірок: неправильна аудиторія, недовірений емітент, некоректний підпис, прострочений термін, видано іншому клієнту, використано раніше або користувач не існує
invalid_scopeЗапит вимагає обсягу, який ID-JAG не надає
invalid_targetresource ID-JAG не є абсолютною URI-адресою
unsupported_grant_typeJWT Bearer відсутній серед типів надання доступу (grant types) додатка клієнта

Метадані сервера авторизації оголошують про підтримку: grant_types_supported містить urn:ietf:params:oauth:grant-type:jwt-bearer, а authorization_grant_profiles_supported містить urn:ietf:params:oauth:grant-profile:id-jag.

Випуск ID-JAG з Casdoor​

Коли Casdoor є IdP компанії, клієнт обмінює ID-токен користувача на ID-JAG на ендпоінті токенів Casdoor за допомогою обміну токенів (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. Додайте Token Exchange до Grant types додатка клієнта.
  2. Зареєструйте MCP-сервер на сторінці LLM AI > MCP Servers організації користувача, вказавши його URL як resource, і виберіть Application, який представляє його. Без resource Casdoor знаходить додаток за audience, як ID клієнта або назву додатка.
  3. Надайте користувачам доступ: додайте дозвіл із Resource type Application, додатком сервера як ресурсом та Effect Allow. Casdoor випускає ID-JAG лише для користувача, якого охоплює дозвіл Allow, тому додаток, якому нікому не надано доступ, залишається закритим.

ID-JAG дійсний протягом 5 хвилин. Його aud — це audience запиту, client_id — ID клієнта додатка, що виконує запит, і він містить email користувача, resource та scope. Сервер авторизації MCP-сервера повинен довіряти емітеру Casdoor, а клієнт повинен використовувати той самий ID клієнта там, наприклад, URL документа метаданих ID клієнта.

Див. також​