Put MCP servers behind the Casdoor MCP gateway, end to end
This guide walks through a complete example: a company publishes one MCP server to its employees, who use it from ChatGPT, Claude, Cursor, and VS Code. Casdoor is both the gateway in front of the server and the authorization server that signs the users in. The MCP server itself needs no OAuth 2.0 code.
Resultados da aprendizagem
- Prepare an organization so that MCP clients register and sign in there.
- Register an MCP server in Casdoor and decide who may use it and which tools.
- Connect the four common MCP clients.
- Serve several organizations from one Casdoor instance.
- Check, audit, and revoke access.
O que você precisa
- A Casdoor instance reachable from the Internet over HTTPS, for example
https://auth.example.com. ChatGPT and Claude custom connectors call it from the cloud. - An MCP server that speaks the Streamable HTTP transport, for example
https://tickets.example.com/mcp, optionally protected by a static bearer token - Acesso de administrador global ao console de administração do Casdoor
The example
Acme runs an MCP server for its ticket system. Acme wants:
- Employees sign in with their Acme account, through the sign-in methods that Acme already set up in Casdoor.
- Only the support team may use the server.
- Nobody may call the tool
delete_ticketthrough an AI client. - The server's own API token never leaves Casdoor.
- An administrator can see and revoke each client.
Step 1: prepare the organization
- In the Casdoor admin console, go to User Management > Organizations and open
acme. - Turn on Use organization issuer. The organization becomes its own authorization server, with the issuer
https://auth.example.com/orgs/acmeand the discovery documenthttps://auth.example.com/.well-known/oauth-authorization-server/orgs/acme. MCP clients that discover it register inacmeand sign users in on the sign-in page ofacme. - Turn on Enable dynamic client registration. This lets clients identify themselves with a client ID metadata document (Claude, VS Code, ChatGPT) or register themselves (Cursor, older clients). Only a global administrator can change this switch.
- Salve a organização.
Without Use organization issuer, the gateway names the global issuer of Casdoor as the authorization server, and clients register in built-in. Turn it on for every organization other than built-in that publishes MCP servers.
Step 2: decide who may use the server
The gateway lets in the users of the server's organization who may sign in to the server's application.
- Go to Identity > Applications and add an application in
acme, for exampleapp-tickets. It needs no redirect URLs: MCP clients don't sign in to it, it only carries the access rules. - To let only the support team in, go to Authorization > Permissions and add a permission in
acme:- Resource type:
Application - Resources:
app-tickets - Groups or Roles: the support team
- Actions:
Read, Effect:Allow
- Resource type:
Sem nenhuma permissão no aplicativo, todos os usuários de acme podem usar o servidor. Administradores de acme e administradores globais sempre podem usá-lo.
Etapa 3: registrar o servidor MCP
-
Acesse LLM AI > MCP Servers e adicione um servidor em
acme:Campo Valor Name ticketsURL https://tickets.example.com/mcpApplication app-ticketsAccess token O token da API do servidor de tickets, se ele precisar de um -
Salve o servidor e selecione Sync sob Tool. O Casdoor busca a lista de ferramentas do servidor.
-
Bloqueie
delete_tickete salve. O gateway responde a uma chamada para uma ferramenta bloqueada, ou para uma ferramenta que não está na lista, com um erro e não a encaminha. -
Copie o Base URL:
https://auth.example.com/api/server/acme/tickets. Esta é a URL que os usuários adicionam aos seus clientes MCP.
O gateway remove o cabeçalho Cookie e o cabeçalho Authorization do usuário de cada solicitação e envia o Access token do servidor em vez disso. O Casdoor nunca retorna o token em suas respostas de API.
Para um servidor de uma organização diferente de built-in, o URL deve ser um endereço público da Internet: o gateway se recusa a alcançar endereços privados e de loopback em nome de um tenant. Para publicar um servidor MCP em sua rede interna, registre-o em built-in.
Etapa 4: verificar a cadeia de descoberta
Todos os clientes MCP seguem a mesma cadeia. Verifique-a com curl antes de conectar um cliente:
curl -i -X POST https://auth.example.com/api/server/acme/tickets
O Casdoor responde HTTP 401 e nomeia os metadados do recurso protegido deste servidor:
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
Neste documento, verifique:
issueréhttps://auth.example.com/orgs/acme, o mesmo valor que emauthorization_servers.client_id_metadata_document_supportedétrue, eregistration_endpointtermina com?organization=acme.token_endpoint_auth_methods_supportedcontémnone, ecode_challenge_methods_supportedcontémS256.
Etapa 5: conectar os clientes
Cada usuário adiciona a URL do gateway ao seu cliente e faz login com sua conta Acme.
| Cliente | Onde adicionar o servidor | Como ele se identifica | Guia |
|---|---|---|---|
| ChatGPT | Plugins > + > Add custom MCP server | CIMD https://chatgpt.com/oauth/client.json | Conectar ChatGPT |
| Claude Desktop, claude.ai | Customize > Connectors > Add custom connector | CIMD https://claude.ai/oauth/mcp-oauth-client-metadata | Conectar Claude |
| Claude Code | claude mcp add --transport http tickets <url> | CIMD https://claude.ai/oauth/claude-code-client-metadata | Conectar Claude |
| Cursor | ~/.cursor/mcp.json | DCR | Conectar Cursor |
| VS Code | .vscode/mcp.json | CIMD https://vscode.dev/oauth/client-metadata.json | Conectar VS Code |
Por exemplo, no Cursor:
{
"mcpServers": {
"tickets": {
"url": "https://auth.example.com/api/server/acme/tickets"
}
}
}
E no VS Code:
{
"servers": {
"tickets": {
"type": "http",
"url": "https://auth.example.com/api/server/acme/tickets"
}
}
}
Um cliente que usa um documento de metadados de ID de cliente obtém um aplicativo no Casdoor, com sua URL como ID de cliente, a tag cimd e um nome que começa com cimd_. Um cliente que se registra obtém um aplicativo por registro, com a tag dcr. Você não cria aplicativos para os clientes.
O que protege o servidor
| Verificação | Onde | O que acontece caso contrário |
|---|---|---|
O token pertence a um usuário de acme | Gateway | HTTP 401 |
O usuário pode fazer login em app-tickets | Gateway | HTTP 401 |
| O token foi emitido para este servidor (RFC 8707) | Gateway | HTTP 401: "The access token is for another resource" |
| A ferramenta está na lista e permitida | Gateway | Erro JSON-RPC, a chamada não é encaminhada |
| O cliente é um cliente que se registrou | Todas as APIs | Seus tokens só podem chamar o fluxo de login, /api/userinfo, /api/mcp e /api/server/*, nunca as APIs de gerenciamento |
Os clientes solicitam o token com resource=https://auth.example.com/api/server/acme/tickets, e o Casdoor coloca essa URL na reivindicação aud. Um token para outro servidor MCP, mesmo um da mesma organização, não funciona aqui, então um servidor malicioso não pode reproduzir os tokens que recebe.
Servir várias organizações
Uma instância do Casdoor pode publicar servidores MCP para várias organizações, por exemplo, os clientes de um SaaS. Repita as etapas 1 a 3 para cada organização. Em seguida:
- Cada organização tem seu próprio emissor (issuer), página de login, usuários e permissões. Um usuário de
globexnão pode fazer login na página deacmenem usar os servidores deacme. - Os documentos de metadados do ID do cliente do ChatGPT, Claude e VS Code possuem uma URL cada, usada por todas as organizações. O Casdoor mantém uma aplicação compartilhada por URL em
built-ine a serve como uma aplicação da organização na qual o usuário faz login. Cada organização ainda deve ativar Enable dynamic client registration para aceitar esses clientes. - Os tokens carregam o emissor (issuer) da organização do usuário, também após uma atualização (refresh).
- Um cliente que se registra sozinho (DCR) registra-se na organização do documento de descoberta, através do parâmetro
organizationdo endpoint de registro.
Verificar, auditar e revogar
- Clients: Identity > Applications lista os clientes com as tags
cimdedcr. Exclua uma aplicaçãodcr_para remover um registro. - Tokens: Auditing > Tokens lista cada token com seu usuário, aplicação, escopo e recurso. Exclua um token para bloquear imediatamente um cliente.
- Users: Proíba um usuário e seus tokens pararão de funcionar no gateway na próxima solicitação.
- Tools: Bloqueie uma ferramenta na página de edição do servidor. A alteração entra em vigor na próxima chamada.
Permitir que usuários corporativos pulem o navegador
Quando os funcionários de uma organização fazem login através de um provedor de identidade corporativo, como Okta, os clientes que suportam Enterprise-Managed Authorization (Claude Team e Enterprise) podem obter o token do gateway sem um login via navegador: o provedor de identidade emite um ID-JAG e o Casdoor o troca por um token de acesso. Veja Enterprise-managed authorization.
Solução de problemas
O gateway responde 401 após o login
- O servidor não possui uma Application. Sem uma, apenas administradores podem usar o servidor. Selecione uma aplicação; veja Etapa 2.
- Uma permissão na aplicação exclui o usuário.
- O usuário pertence a uma organização diferente da do servidor.
- O cliente solicitou o token para outro recurso. Verifique a claim
auddo token: ela deve ser a URL do gateway.
O cliente faz login dos usuários na organização errada
Use organization issuer está desativado, então os metadados do recurso protegido nomeiam o emissor global. Ative-o e reconecte o cliente.
"documents de metadados do ID do cliente não são aceitos"
Enable dynamic client registration está desativado para a organização. O Casdoor também precisa alcançar a URL do documento do cliente pela Internet.
O gateway responde 502
O Casdoor não consegue alcançar a URL do servidor. Verifique a URL e, para uma organização que não seja built-in, se é um endereço público.