Розміщення серверів MCP за шлюзом Casdoor MCP: комплексне рішення
Цей посібник розглядає комплексний приклад: компанія публікує один сервер MCP для своїх співробітників, які використовують його через ChatGPT, Claude, Cursor та VS Code. Casdoor виступає одночасно як шлюз перед сервером і як сервер авторизації, який здійснює вхід користувачів. Самому серверу MCP не потрібно писати код для OAuth 2.0.
Результати навчання
- Підготуйте організацію так, щоб клієнти MCP реєструвалися та входили в неї.
- Зареєструйте сервер MCP у Casdoor і визначте, хто може його використовувати та які інструменти.
- Підключіть чотири поширені клієнти MCP.
- Обслуговуйте кілька організацій з одного екземпляра Casdoor.
- Перевіряйте, аудитуйте та відкликайте доступ.
Що потрібно
- Екземпляр Casdoor, доступний з Інтернету через HTTPS, наприклад
https://auth.example.com. Власні конектори ChatGPT і Claude звертаються до нього з хмари. - Сервер MCP, який підтримує транспорт Streamable HTTP, наприклад
https://tickets.example.com/mcp, необов'язково захищений статичним токеном носія (bearer token) - Глобальний доступ адміністратора до адміністративної консолі Casdoor
Приклад
Компанія Acme керує сервером MCP для своєї системи тікетів. Acme хоче:
- Співробітники входять під обліковими записами Acme через способи входу, які Acme вже налаштувала в Casdoor.
- Лише команда підтримки може використовувати сервер.
- Ніхто не може викликати інструмент
delete_ticketчерез ШІ-клієнт. - Власний API-токен сервера ніколи не залишає межі Casdoor.
- Адміністратор може переглядати та відкликати доступ для кожного клієнта.
Крок 1: підготовка організації
- У адміністративній консолі Casdoor перейдіть до User Management > Organizations і відкрийте
acme. - Увімкніть Use organization issuer. Організація стає власним сервером авторизації з емітентом
https://auth.example.com/orgs/acmeта документом виявленняhttps://auth.example.com/.well-known/oauth-authorization-server/orgs/acme. Клієнти MCP, які виявляють його, реєструються вacmeта входять користувачів на сторінці входуacme. - Увімкніть Enable dynamic client registration. Це дозволяє клієнтам ідентифікувати себе за допомогою документа метаданих ідентифікатора клієнта (Claude, VS Code, ChatGPT) або реєструватися самостійно (Cursor, старіші клієнти). Лише глобальний адміністратор може змінювати цей перемикач.
- Збережіть організацію.
Без Use organization issuer шлюз називає глобальний емітент Casdoor як сервер авторизації, а клієнти реєструються в built-in. Увімкніть цю опцію для кожної організації, окрім built-in, яка публікує сервери MCP.
Крок 2: визначення того, хто може використовувати сервер
Шлюз пропускає користувачів організації сервера, які можуть увійти в застосунок сервера.
- Перейдіть до Identity > Applications і додайте застосунок в
acme, наприкладapp-tickets. Йому не потрібні URL-адреси переспрямування: клієнти MCP не входять у нього, він лише містить правила доступу. - Щоб пропустити лише команду підтримки, перейдіть до Authorization > Permissions і додайте дозвіл в
acme:- Resource type:
Application - Resources:
app-tickets - Groups або Roles: команда підтримки
- Actions:
Read, Effect:Allow
- Resource type:
Без жодних дозволів для додатка кожен користувач acme може використовувати сервер. Адміністратори acme та глобальні адміністратори завжди можуть його використовувати.
Крок 3: зареєструйте MCP-сервер
-
Перейдіть до LLM AI > MCP Servers і додайте сервер в
acme:Поле Значення Name ticketsURL https://tickets.example.com/mcpApplication app-ticketsAccess token API-токен сервера квитків, якщо він потрібен -
Збережіть сервер, а потім оберіть Sync під розділом Tool. Casdoor завантажує список інструментів сервера.
-
Заблокуйте
delete_ticketі збережіть зміни. Шлюз відповідає помилкою на виклик заблокованого інструмента або інструмента, якого немає в списку, і не пересилає його далі. -
Скопіюйте Base URL:
https://auth.example.com/api/server/acme/tickets. Це URL, який користувачі додають у свої MCP-клієнти.
Шлюз видаляє заголовок Cookie і заголовок Authorization користувача з кожного запиту та надсилає натомість Access token сервера. Casdoor ніколи не повертає цей токен у своїх відповідях API.
Для сервера організації, відмінної від built-in, поле URL має бути публічною адресою в Інтернеті: шлюз відмовляється звертатися до приватних і петльових (loopback) адрес від імені орендаря. Щоб оприлюднити MCP-сервер у вашій внутрішній мережі, зареєструйте його в built-in.
Крок 4: перевірте ланцюжок виявлення
Кожен MCP-клієнт дотримується тієї самої ланцюжки. Перевірте її за допомогою curl, перш ніж підключати клієнт:
curl -i -X POST https://auth.example.com/api/server/acme/tickets
Casdoor відповідає HTTP 401 і вказує метадані захищеного ресурсу цього сервера:
WWW-Authenticate: Bearer realm="casdoor", resource_metadata="https://auth.example.com/.well-known/oauth-protected-resource/api/server/acme/tickets"
curl https://auth.example.com/.well-known/oauth-protected-resource/api/server/acme/tickets
{
"resource": "https://auth.example.com/api/server/acme/tickets",
"authorization_servers": ["https://auth.example.com/orgs/acme"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["openid", "profile", "email", "offline_access"]
}
curl https://auth.example.com/.well-known/oauth-authorization-server/orgs/acme
У цьому документі перевірте:
issuer— цеhttps://auth.example.com/orgs/acme, те саме значення, що й уauthorization_servers.client_id_metadata_document_supportedдорівнюєtrue, аregistration_endpointзакінчується на?organization=acme.token_endpoint_auth_methods_supportedміститьnone, аcode_challenge_methods_supportedміститьS256.
Крок 5: підключіть клієнти
Кожен користувач додає URL шлюзу до свого клієнта та входить через свій обліковий запис Acme.
| Клієнт | Де додати сервер | Як він ідентифікує себе | Посібник |
|---|---|---|---|
| ChatGPT | Plugins > + > Add custom MCP server | CIMD https://chatgpt.com/oauth/client.json | Підключення ChatGPT |
| Claude Desktop, claude.ai | Customize > Connectors > Add custom connector | CIMD https://claude.ai/oauth/mcp-oauth-client-metadata | Підключення Claude |
| Claude Code | claude mcp add --transport http tickets <url> | CIMD https://claude.ai/oauth/claude-code-client-metadata | Підключення Claude |
| Cursor | ~/.cursor/mcp.json | DCR | Підключення Cursor |
| VS Code | .vscode/mcp.json | CIMD https://vscode.dev/oauth/client-metadata.json | Підключення VS Code |
Наприклад, у Cursor:
{
"mcpServers": {
"tickets": {
"url": "https://auth.example.com/api/server/acme/tickets"
}
}
}
А у VS Code:
{
"servers": {
"tickets": {
"type": "http",
"url": "https://auth.example.com/api/server/acme/tickets"
}
}
}
Клієнт, який використовує документ метаданих ідентифікатора клієнта, отримує один додаток у Casdoor, де URL є ідентифікатором клієнта, тег cimd та назва починається з cimd_. Клієнт, який реєструється самостійно, отримує один додаток на кожну реєстрацію з тегом dcr. Вам не потрібно створювати додатки для клієнтів вручну.
Що захищає сервер
| Перевірка | Де | Що відбувається інакше |
|---|---|---|
Токен належить користувачу acme | Шлюз | HTTP 401 |
Користувач має право входити в app-tickets | Шлюз | HTTP 401 |
| Токен було видано для цього сервера (RFC 8707) | Шлюз | HTTP 401: "The access token is for another resource" |
| Інструмент є в списку та дозволений | Шлюз | Помилка JSON-RPC, виклик не пересилається |
| Клієнт зареєструвався самостійно | Кожен API | Його токени можуть викликати лише процес входу, /api/userinfo, /api/mcp та /api/server/*, але ніколи керуючі API |
Клієнти надсилають запит на токен із resource=https://auth.example.com/api/server/acme/tickets, і Casdoor поміщає цей URL у твердження aud. Токен для іншого MCP-сервера, навіть тієї ж організації, тут не працюватиме, тому зловмисний сервер не зможе повторно використати отримані ним токени.
Обслуговування кількох організацій
Один екземпляр Casdoor може публікувати MCP-сервери для багатьох організацій, наприклад, для клієнтів SaaS. Повторіть кроки 1–3 для кожної організації. Потім:
- Кожна організація має власний емітент (issuer), сторінку входу, користувачів і дозволи. Користувач
globexне може увійти на сторінціacmeі не може використовувати сервериacme. - Документи метаданих ідентифікаторів клієнта (client ID metadata documents) для ChatGPT, Claude та VS Code мають по одному URL, який використовується всіма організаціями. Casdoor зберігає один спільний додаток для кожного такого URL у
built-inі подає його як додаток тієї організації, до якої входить користувач. Кожній організації все одно потрібно увімкнути Enable dynamic client registration, щоб приймати цих клієнтів. - Токени містять емітент організації користувача, навіть після оновлення (refresh).
- Клієнт, який реєструється самостійно (DCR), реєструється в організації, зазначеній у документі виявлення (discovery document), через параметр
organizationкінцевої точки реєстрації.
Перевірка, аудит і відкликання
- Clients: Identity > Applications перелічує клієнти з тегами
cimdіdcr. Видалення додаткаdcr_прибирає реєстрацію. - Tokens: Auditing > Tokens перелічує кожен токен із його користувачем, додатком, областю дії (scope) та ресурсом. Видалення токена миттєво відриває клієнта.
- Users: Заборона користувачу призводить до того, що їхні токени перестають працювати на шлюзі під час наступного запиту.
- Tools: Блокування інструменту на сторінці редагування сервера. Зміна вступає в силу під час наступного виклику.
Дозвольте корпоративним користувачам пропускати браузер
Коли співробітники організації входять через корпоративного постачальника ідентичності, такого як Okta, клієнти, які підтримують Enterprise-Managed Authorization (Claude Team і Enterprise), можуть отримати токен шлюза без входу через браузер: постачальник ідентичності видає ID-JAG, а Casdoor обмінює його на токен доступу. Див. Enterprise-managed authorization.
Усунення несправностей
Шлюз відповідає помилкою 401 після входу
- У сервера немає Application. Без нього лише адміністратори можуть використовувати сервер. Виберіть додаток, див. Step 2.
- Дозвіл на додаток виключає користувача.
- Користувач належить до іншої організації, ніж сервер.
- Клієнт запросив токен для іншого ресурсу. Перевірте твердження
audу токені: воно повинно відповідати URL шлюза.
Клієнт входить користувачів у неправильну організацію
Опція Use organization issuer вимкнена, тому метадані захищеного ресурсу вказують глобальний емітент. Увімкніть її та повторно підключіть клієнт.
"документи метаданих ідентифікатора клієнта не приймаються"
Опція Enable dynamic client registration вимкнена для організації. Casdoor також повинен мати доступ до URL документа клієнта через Інтернет.
Шлюз відповідає помилкою 502
Casdoor не може досягти URL сервера. Перевірте URL і, якщо організація відрізняється від built-in, переконайтеся, що це публічна адреса.