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

Розміщення серверів 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: підготовка організації​

  1. У адміністративній консолі Casdoor перейдіть до User Management > Organizations і відкрийте acme.
  2. Увімкніть Use organization issuer. Організація стає власним сервером авторизації з емітентом https://auth.example.com/orgs/acme та документом виявлення https://auth.example.com/.well-known/oauth-authorization-server/orgs/acme. Клієнти MCP, які виявляють його, реєструються в acme та входять користувачів на сторінці входу acme.
  3. Увімкніть Enable dynamic client registration. Це дозволяє клієнтам ідентифікувати себе за допомогою документа метаданих ідентифікатора клієнта (Claude, VS Code, ChatGPT) або реєструватися самостійно (Cursor, старіші клієнти). Лише глобальний адміністратор може змінювати цей перемикач.
  4. Збережіть організацію.

Без Use organization issuer шлюз називає глобальний емітент Casdoor як сервер авторизації, а клієнти реєструються в built-in. Увімкніть цю опцію для кожної організації, окрім built-in, яка публікує сервери MCP.

Крок 2: визначення того, хто може використовувати сервер​

Шлюз пропускає користувачів організації сервера, які можуть увійти в застосунок сервера.

  1. Перейдіть до Identity > Applications і додайте застосунок в acme, наприклад app-tickets. Йому не потрібні URL-адреси переспрямування: клієнти MCP не входять у нього, він лише містить правила доступу.
  2. Щоб пропустити лише команду підтримки, перейдіть до Authorization > Permissions і додайте дозвіл в acme:
    • Resource type: Application
    • Resources: app-tickets
    • Groups або Roles: команда підтримки
    • Actions: Read, Effect: Allow

Без жодних дозволів для додатка кожен користувач acme може використовувати сервер. Адміністратори acme та глобальні адміністратори завжди можуть його використовувати.

Крок 3: зареєструйте MCP-сервер​

  1. Перейдіть до LLM AI > MCP Servers і додайте сервер в acme:

    ПолеЗначення
    Nametickets
    URLhttps://tickets.example.com/mcp
    Applicationapp-tickets
    Access tokenAPI-токен сервера квитків, якщо він потрібен
  2. Збережіть сервер, а потім оберіть Sync під розділом Tool. Casdoor завантажує список інструментів сервера.

  3. Заблокуйте delete_ticket і збережіть зміни. Шлюз відповідає помилкою на виклик заблокованого інструмента або інструмента, якого немає в списку, і не пересилає його далі.

  4. Скопіюйте 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.

КлієнтДе додати серверЯк він ідентифікує себеПосібник
ChatGPTPlugins > + > Add custom MCP serverCIMD https://chatgpt.com/oauth/client.jsonПідключення ChatGPT
Claude Desktop, claude.aiCustomize > Connectors > Add custom connectorCIMD https://claude.ai/oauth/mcp-oauth-client-metadataПідключення Claude
Claude Codeclaude mcp add --transport http tickets <url>CIMD https://claude.ai/oauth/claude-code-client-metadataПідключення Claude
Cursor~/.cursor/mcp.jsonDCRПідключення Cursor
VS Code.vscode/mcp.jsonCIMD 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, переконайтеся, що це публічна адреса.

Див. також​