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
-
У адміністративній консолі Casdoor перейдіть до User Management > Organizations і відкрийте організацію користувачів, наприклад
acme. -
За бажанням увімкніть Use organization issuer, щоб організація мала власний емітент,
https://your-casdoor.com/orgs/acme. В іншому випадку емітентом буде глобальний,https://your-casdoor.com. -
У розділі Trusted ID-JAG issuers додайте рядок:
Column Value Issuer Значення issдля ID-JAG, наприкладhttps://acme.okta.comJWKS URL Набір ключів IdP. Якщо залишити пустим, Casdoor читає jwks_uriз<issuer>/.well-known/openid-configurationUser Як знайти користувача в організації: {email}(за замовчуванням) використовує твердженняemail,{sub}— твердженняsub, будь-яке{claim}— відповідне твердження. Casdoor зіставляє його з ім'ям користувача, email, телефоном та ID -
Збережіть налаштування організації. Лише глобальний адміністратор може змінювати довірені емітенти.
У 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.
Помилки
| Error | Cause |
|---|---|
invalid_client | Конфіденційний клієнт не пройшов автентифікацію |
invalid_grant | ID-JAG не пройшов одну з перевірок: неправильна аудиторія, недовірений емітент, некоректний підпис, прострочений термін, видано іншому клієнту, використано раніше або користувач не існує |
invalid_scope | Запит вимагає обсягу, який ID-JAG не надає |
invalid_target | resource ID-JAG не є абсолютною URI-адресою |
unsupported_grant_type | JWT 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"
}
Налаштуйте це наступним чином:
- Додайте Token Exchange до Grant types додатка клієнта.
- Зареєструйте MCP-сервер на сторінці LLM AI > MCP Servers організації користувача, вказавши його URL як
resource, і виберіть Application, який представляє його. БезresourceCasdoor знаходить додаток заaudience, як ID клієнта або назву додатка. - Надайте користувачам доступ: додайте дозвіл із Resource type
Application, додатком сервера як ресурсом та EffectAllow. Casdoor випускає ID-JAG лише для користувача, якого охоплює дозвілAllow, тому додаток, якому нікому не надано доступ, залишається закритим.
ID-JAG дійсний протягом 5 хвилин. Його aud — це audience запиту, client_id — ID клієнта додатка, що виконує запит, і він містить email користувача, resource та scope. Сервер авторизації MCP-сервера повинен довіряти емітеру Casdoor, а клієнт повинен використовувати той самий ID клієнта там, наприклад, URL документа метаданих ID клієнта.