Pular para o conteúdo

Servidores de recurso

Registre a sua API num realm, peça tokens endereçados a ela com o parâmetro resource (RFC 8707) e valide-os na API.

Um servidor de recurso é uma API — um serviço REST, um servidor MCP — que aceita os access tokens de um realm. Registrá-lo dá a ele um identificador que os tokens carregam como audiência (aud), um conjunto de escopos próprios e a lista de clients que podem pedir tokens para ele.

A audiência importa porque todos os clients de um realm publicam as chaves de assinatura no mesmo conjunto de chaves: uma assinatura válida só prova que o token veio do realm. É a audiência que diz que ele foi feito para a sua API, e assim um token emitido para outra aplicação do mesmo realm é recusado.

Servidores de recurso exigem um plano que inclua a integração MCP. Sem ela, eles continuam visíveis no console, mas não é possível registrar novos e nenhum token é emitido para eles.

Registre uma API

Abra Servidores de recurso, escolha Novo servidor de recurso e selecione o realm cujos tokens a API vai aceitar.

CampoRegras
IdentificadorA URL http ou https canônica da API, como https://api.acme.com, sem fragmento e com até 512 caracteres. Esquema e host vão para minúsculas, e a porta padrão e a barra final são removidas. Único no realm e fixo depois de criado, porque todo token emitido para ele o carrega.
Nome e descriçãoAté 128 e 512 caracteres.
EscoposPelo menos um, como documents:read. Até 128 caracteres cada, sem espaços, aspas ou barras invertidas, diferenciando maiúsculas e sem repetição.
Clients autorizadosOs clients do mesmo realm que podem pedir tokens para ele. Estar no realm não basta.
Aceitar clientes CIMDDeixa clientes MCP que se registraram sozinhos com um Client ID Metadata Document pedirem tokens para ele.
Cliente de introspecçãoUm client confidencial do realm que a API usa para perguntar se um token ainda vale.
  • Desativar mantém o identificador, os escopos e os clients, e para na hora de emitir tokens novos para ele.
  • Excluir remove os escopos e a lista de clients e não mexe nos clients em si; os tokens já emitidos valem até expirar.
  • Na edição, os escopos e clients salvos substituem os anteriores.

Peça tokens para uma API

Nomeie a API com o parâmetro resource da RFC 8707 e peça os escopos dela em scope. Uma requisição de autorização aceita no máximo um resource.

Requisição de autorizaçãoTexto simples
https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/auth
  ?client_id=acme-web
  &response_type=code
  &redirect_uri=https%3A%2F%2Fapp.acme.com%2Fapi%2Fauth%2Fcallback%2Fauthio
  &scope=openid%20documents%3Aread
  &resource=https%3A%2F%2Fapi.acme.com
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
  &state=af0ifjsldkj
  • Na troca do código, resource pode ser omitido; se for enviado, precisa ser igual ao da requisição de autorização.
  • Os refreshes mantêm o resource da autorização original, então os tokens renovados continuam endereçados à mesma API.
  • O servidor de recurso e o acesso do client a ele são conferidos de novo a cada emissão, inclusive nos refreshes: um servidor desativado, ou um client retirado da lista, para de receber tokens na hora.
ErroPor quê
invalid_targetMais de um resource, ou um que não nomeia nenhum servidor de recurso ativo para o qual este client possa pedir tokens.
invalid_scopeUm escopo pedido não está habilitado no client nem é um dos escopos do servidor.
access_deniedO plano não inclui a integração MCP.

O que o token carrega

O aud do access token é o identificador, e o scope dele soma os escopos do servidor que a requisição pediu aos que o client recebeu. Sem resource, o aud é a audiência configurada no client.

Payload do access tokenJSON
{
  "iss": "https://authio.api.hyperio.tech/realms/acme",
  "sub": "6f1c2e7a-4b8d-4f0e-9a51-3c2d7e8b9f10",
  "aud": "https://api.acme.com",
  "azp": "acme-web",
  "typ": "Bearer",
  "scope": "openid documents:read",
  "iat": 1791370800,
  "nbf": 1791370800,
  "exp": 1791372600
}

Valide access tokens na sua API

Access tokens são JWTs assinados, então a sua API os valida sozinha com as chaves públicas do realm, sem chamar o Authio a cada requisição. Em toda requisição, confira:

ConferênciaEsperado
AssinaturaUma chave do JWKS do realm, https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/certs, escolhida pelo cabeçalho kid
isshttps://authio.api.hyperio.tech/realms/acme
audO identificador da sua API, https://api.acme.com
exp e nbfO momento atual está dentro da janela
typBearer. ID tokens trazem ID e refresh tokens, Refresh.
scopeContém o escopo que o endpoint exige
verify.tsTypeScript
import { createRemoteJWKSet, jwtVerify } from 'jose'

const issuer = 'https://authio.api.hyperio.tech/realms/acme'
const jwks = createRemoteJWKSet(
  new URL(`${issuer}/protocol/openid-connect/certs`),
)

export async function verifyAccessToken(token: string, requiredScope: string) {
  const { payload } = await jwtVerify(token, jwks, {
    issuer,
    audience: 'https://api.acme.com',
  })

  if (payload.typ !== 'Bearer') {
    throw new Error('Not an access token')
  }

  const scopes = typeof payload.scope === 'string' ? payload.scope.split(' ') : []

  if (!scopes.includes(requiredScope)) {
    throw new Error(`Missing scope ${requiredScope}`)
  }

  return payload
}

O handler de JWT bearer lê o emissor e as chaves no documento de discovery do realm e confere sozinho assinatura, emissor, audiência e validade. Para ASP.NET Core também existe um pacote do Authio; veja .NET.

Confira revogações com introspecção

Um token validado localmente continua válido até expirar, mesmo depois que a sessão dele terminou ou que o usuário foi suspenso. Quando a API precisa saber na hora, pergunte ao realm com o cliente de introspecção do servidor (RFC 7662):

RequisiçãoBash
curl -X POST https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/introspect \
  -u "acme-api:YOUR_CLIENT_SECRET" \
  -d "token=$ACCESS_TOKEN" \
  -d "token_type_hint=access_token"
  • A resposta é sempre 200. Um token expirado, revogado, de uma sessão encerrada ou que nunca foi válido recebe só {"active": false}, sem motivo.
  • O cliente de introspecção enxerga os tokens endereçados aos servidores de recurso dele, mesmo quando outro client os pediu.
  • Uma resposta ativa também traz as claims de papéis, acr, amr, a organização e, em tokens delegados, act e delegation_id.

Atividade

A aba Atividade do servidor de recurso conta, em 7, 30 ou 90 dias, os tokens emitidos e recusados para ele, as trocas de contas conectadas que ele fez e as introspecções que rodou, com os clients e usuários mais ativos e os motivos de recusa mais comuns.

Próximos passos

Cookies de analytics

Gostaríamos de medir como o console é usado, com o Google Analytics, para enxergar em quais telas as pessoas travam. Isso grava um cookie que reconhece este navegador na sua próxima visita.

Recusar não muda mais nada. Os cookies que mantêm você conectado e lembram o seu idioma e o seu tema são necessários para o console funcionar, e ficam de qualquer forma. Ler a Política de Privacidade