Pular para o conteúdo principal

Autorização gerenciada por empresa com ID-JAG

Este guia explica a Enterprise-Managed Authorization, uma extensão da especificação de autorização MCP para empresas: o provedor de identidade corporativo (IdP) decide quais servidores MCP um funcionário pode usar, e o cliente MCP obtém seus tokens sem um login via navegador em cada servidor. O Casdoor assume qualquer um dos papéis:

  • O servidor de autorização dos servidores MCP: O Casdoor aceita os ID-JAGs de um IdP corporativo confiável para a organização.
  • O IdP corporativo: O Casdoor emite ID-JAGs para servidores MCP cujo servidor de autorização confia nele.

Resultados da aprendizagem​

  • Entenda o fluxo e o que é um ID-JAG.
  • Permita que uma organização do Casdoor confie nos ID-JAGs de um IdP corporativo.
  • Emita ID-JAGs a partir do Casdoor.

O que você precisa​

  • Acesso de administrador global ao console de administração do Casdoor
  • Um cliente MCP que suporte a extensão, por exemplo, Claude Team ou Enterprise com Okta Cross App Access

Como funciona​

Um ID-JAG (Identity Assertion JWT Authorization Grant) é um JWT de curta duração assinado pelo IdP. Ele afirma: este usuário pode usar este cliente neste servidor de autorização. Ele é definido em draft-ietf-oauth-identity-assertion-authz-grant, e a extensão MCP io.modelcontextprotocol/enterprise-managed-authorization baseia-se nele. Veja Enterprise-Managed Authorization.

O usuário nunca vê a página de login do Casdoor. Quando o IdP bloqueia o usuário, por exemplo, após ele deixar a empresa, o cliente não recebe novos ID-JAGs, nem novos tokens de acesso.

Aceitar ID-JAGs no Casdoor​

Confiar no IdP​

  1. No console de administração do Casdoor, vá para User Management > Organizations e abra a organização dos usuários, por exemplo, acme.

  2. Opcionalmente, ative Use organization issuer, para que a organização tenha seu próprio emissor, https://your-casdoor.com/orgs/acme. Caso contrário, o emissor será o global, https://your-casdoor.com.

  3. Em Trusted ID-JAG issuers, adicione uma linha:

    ColumnValue
    IssuerO iss dos ID-JAGs, por exemplo, https://acme.okta.com
    JWKS URLO conjunto de chaves do IdP. Se você deixá-lo vazio, o Casdoor lê jwks_uri de <issuer>/.well-known/openid-configuration
    UserComo encontrar o usuário na organização: {email} (o padrão) usa a claim email, {sub} usa a claim sub, qualquer {claim} usa aquela claim. O Casdoor faz a correspondência contra o nome de usuário, email, telefone e ID
  4. Salve a organização. Apenas um administrador global pode alterar os emissores confiáveis.

No IdP, dê ao Casdoor o emissor da organização como audiência dos ID-JAGs, e as URLs dos servidores MCP como recursos. Para um servidor atrás do MCP gateway, isso é https://your-casdoor.com/api/server/acme/<server-name>.

Deixe o cliente usar a concessão​

O cliente resgata o ID-JAG no endpoint de token usando a concessão de portador JWT (urn:ietf:params:oauth:grant-type:jwt-bearer), portanto, o tipo de concessão deve ser permitido para sua aplicação:

  • Claude: Seu documento de metadados de ID de cliente https://claude.ai/oauth/mcp-oauth-client-metadata lista a concessão. Ative Enable dynamic client registration para a organização, para que o Casdoor aceite o documento. Veja Connect Claude.
  • Uma aplicação que você criar: Adicione JWT Bearer aos seus Grant types.

O que o cliente envia​

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>

O Casdoor responde com um token de acesso cuja audiência é o resource do ID-JAG:

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 604800,
"scope": "openid profile"
}

O que o Casdoor verifica​

VerificaçãoRegra
TipoO cabeçalho do JWT tem typ: oauth-id-jag+jwt. Outras asserções passam pela concessão de portador JWT comum
ClienteUm cliente confidencial se autentica, com seu segredo de cliente ou private_key_jwt. Um cliente público de um documento de metadados de ID de cliente, como o Claude, não tem segredo e envia apenas client_id
Audiênciaaud é o emissor de uma organização com seu próprio emissor, ou o emissor global, que representa a organização da aplicação do cliente
Emissor e assinaturaiss é um emissor confiável dessa organização, e a chave com o kid do cabeçalho em seu JWKS verifica a assinatura
Validadeexp e iat estão presentes e são válidos, com um minuto de tolerância
Vínculo do clienteclient_id é igual ao ID do cliente do cliente que o resgata
Uso únicoO Casdoor aceita cada jti de um emissor uma única vez
UsuárioO usuário encontrado através de User existe na organização, não está bloqueado e pode fazer login na aplicação do cliente
EscopoUm scope na solicitação deve ser um subconjunto do scope do ID-JAG. Sem um, o token obtém o escopo do ID-JAG
Recursoresource, quando presente, torna-se a audiência do token de acesso

Um cliente que se registrou automaticamente (DCR) ou usa um documento de metadados de ID de cliente pode usar a concessão de portador JWT apenas com um ID-JAG.

Erros​

ErrorCause
invalid_clientUm cliente confidencial não se autenticou
invalid_grantO ID-JAG falhou em uma das verificações: audiência incorreta, emissor não confiável, assinatura inválida, expirado, emitido para outro cliente, usado anteriormente, ou o usuário não existe
invalid_scopeA solicitação pede um escopo que o ID-JAG não concede
invalid_targetO resource do ID-JAG não é uma URI absoluta
unsupported_grant_typeO JWT Bearer não está entre os tipos de concessão da aplicação do cliente

Os metadados do servidor de autorização anunciam o suporte: grant_types_supported contém urn:ietf:params:oauth:grant-type:jwt-bearer, e authorization_grant_profiles_supported contém urn:ietf:params:oauth:grant-profile:id-jag.

Emitir ID-JAGs pelo Casdoor​

Quando o Casdoor é o IdP da empresa, um cliente troca o token de ID do usuário por um ID-JAG no endpoint de token do Casdoor, usando a troca de tokens (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"
}

Configure-o da seguinte forma:

  1. Adicione Token Exchange aos Grant types da aplicação do cliente.
  2. Registre o servidor MCP na página LLM AI > MCP Servers da organização do usuário, com sua URL como resource, e selecione uma Application que o represente. Sem um resource, o Casdoor encontra a aplicação pelo audience, como um client ID ou nome da aplicação.
  3. Conceda acesso aos usuários: adicione uma permissão com Resource type Application, a aplicação do servidor como recurso, e Effect Allow. O Casdoor emite um ID-JAG apenas para um usuário coberto por uma permissão Allow, então uma aplicação sem concedida permanece fechada.

O ID-JAG é válido por 5 minutos. Seu aud é o audience da solicitação, client_id é o client ID da aplicação solicitante, e ele carrega o email do usuário, o resource e o scope. O servidor de autorização do servidor MCP deve confiar no emissor do Casdoor, e o cliente deve usar o mesmo client ID lá, por exemplo, a URL do documento de metadados do seu client ID.

Veja também​