Pular para o conteúdo

Endpoints OpenID Connect

Todos os endereços de protocolo de um realm — discovery, JWKS, autorização, token, UserInfo, introspecção, revogação, logout e autorização de dispositivo —, com parâmetros e exemplos.

Cada realm é um OpenID Provider independente. O emissor dele é {base}/realms/{realm} e todos os endpoints ficam abaixo dele, então um client configurado com o emissor encontra o resto pelo discovery. Os exemplos desta página usam o realm acme na plataforma compartilhada:

EmissorTexto simples
https://authio.api.hyperio.tech/realms/acme

Num ambiente dedicado, troque o host pelo endereço da API do seu ambiente. Um token emitido por um realm nunca é aceito por outro.

Os endpoints num relance

EndpointMétodoCaminho abaixo do emissorLimite de taxa
DiscoveryGET/.well-known/openid-configurationNenhum
JWKSGET/protocol/openid-connect/certsNenhum
AutorizaçãoGET/protocol/openid-connect/auth300 por minuto
TokenPOST/protocol/openid-connect/token50 por minuto
UserInfoGET, POST/protocol/openid-connect/userinfo300 por minuto
IntrospecçãoPOST/protocol/openid-connect/introspect50 por minuto
RevogaçãoPOST/protocol/openid-connect/revoke50 por minuto
LogoutGET/protocol/openid-connect/logout50 por minuto
Autorização de dispositivoPOST/protocol/openid-connect/device/auth50 por minuto

Os limites contam cada chamador por realm. Uma requisição recusada recebe 429 com o cabeçalho Retry-After. As respostas que levam credenciais — token, introspecção, revogação, UserInfo, autorização de dispositivo — saem com Cache-Control: no-store.

Discovery

Os metadados do provedor são servidos em três endereços, para que o client os encontre seja qual for a convenção que ele segue: o OpenID Connect Discovery acrescenta o sufixo ao emissor, e o RFC 8414 o insere depois do host, a forma que os clients MCP tentam primeiro.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/.well-known/openid-configuration
curl https://authio.api.hyperio.tech/.well-known/oauth-authorization-server/realms/acme
curl https://authio.api.hyperio.tech/.well-known/openid-configuration/realms/acme

O documento descreve o realm como ele está configurado, e não um catálogo genérico:

CampoValor
scopes_supported, grant_types_supportedTudo o que os clients do realm permitem, somado.
code_challenge_methods_supportedOs métodos PKCE que os clients do realm permitem; S256 quando nenhum está definido.
response_types_supportedcode
response_modes_supportedquery, web_message
display_values_supportedpage, popup
token_endpoint_auth_methods_supportedclient_secret_basic, client_secret_post, none — os mesmos para introspecção e revogação.
id_token_signing_alg_values_supportedRS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512
subject_types_supportedpublic
acr_values_supported1, 2, 3
prompt_values_supportednone, login, select_account, consent
authorization_response_iss_parameter_supportedtrue
frontchannel_logout_supported, backchannel_logout_supportedtrue, com os respectivos _session_supported.
client_id_metadata_document_supportedtrue só quando o realm aceita clients que se registram a partir da URL de um metadata document.

Não há endpoint de registro dinâmico de clients, e request objects assinados (request, request_uri) não são aceitos. O discovery responde 404 para um realm que não existe.

JWKS

As chaves públicas que validam os tokens do realm, como um JWK Set (RFC 7517). Todo token informa no cabeçalho kid a chave que o assinou. As chaves são rotacionadas periodicamente, então guarde o conjunto em cache e busque de novo quando um token trouxer um kid que você não tem.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/certs

Endpoint de autorização

Inicia um login com o fluxo authorization code. O navegador é enviado para cá, o login hospedado executa os passos de login do client e o navegador volta ao seu redirect_uri com um código.

ParâmetroObrigatórioObservações
client_idSimO ID do client, como acme-web.
redirect_uriSimPrecisa ser igual a um dos redirect URIs registrados no client: esquema, host, porta, caminho e query.
response_typeSimcode, o único aceito.
scopeSimSeparados por espaço. Precisa incluir openid, a menos que o client seja OAuth 2.0 puro, e todo escopo precisa estar habilitado no client. Inclua offline_access para receber um refresh token.
code_challenge, code_challenge_methodCom PKCE ligado — o padrãoS256 ou plain, conforme o client permitir. Um challenge sem método é recusado.
stateRecomendadoVolta inalterado na resposta.
nonceRecomendadoCopiado para o ID token.
promptNãonone, login, select_account ou consent. none não combina com outro valor.
max_ageNãoSegundos desde o último login a partir dos quais a pessoa entra de novo.
id_token_hint, login_hintNãoUm ID token que este realm emitiu para o client; um identificador para preencher a tela de login.
acr_valuesNão1 um fator, 2 multifator, 3 resistente a phishing. É uma preferência: nunca recusa o login.
resourceNãoUm URI de servidor de recurso (RFC 8707), que vira a audiência do access token.
organizationNãoO alias da organização para a qual o login é feito.
ui_localesNãoIdiomas preferidos para as telas, do mais preferido ao menos.
response_mode, displayNãoquery (o padrão) e page; web_message e popup para um login numa janela popup.
Pedido 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%2Fcallback
  &scope=openid%20profile%20email%20offline_access
  &state=af0ifjsldkj
  &nonce=n-0S6_WzA2Mj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

A resposta traz code, state e iss (RFC 9207). O código vale 30 segundos e uma única vez: apresentá-lo de novo revoga a sessão em que ele foi emitido. Enquanto o redirect_uri não está comprovado, os erros aparecem numa tela de erro em vez de serem redirecionados; depois disso, voltam ao redirect_uri com error, error_description, state e iss.

Endpoint de token

Troca um grant por tokens. O corpo é application/x-www-form-urlencoded. Um client confidencial se autentica por HTTP Basic (client_secret_basic, o padrão) ou com client_id e client_secret no corpo (client_secret_post) — só o método registrado no client é aceito, e o Basic vale quando os dois são enviados. Um client público envia só o client_id e conta com o PKCE. Autenticação de client por JWT com chave privada não é aceita.

Grants aceitos

Grantgrant_typeRefresh token
Authorization codeauthorization_codeCom offline_access
Refresh tokenrefresh_tokenRotacionado a cada uso, por padrão
Client credentialsclient_credentialsNão
SenhapasswordSó quando o client permite
Device codeurn:ietf:params:oauth:grant-type:device_codeCom offline_access
Token exchangeurn:ietf:params:oauth:grant-type:token-exchangeNão
Personal access tokenpersonal_access_tokenNão

Cada grant precisa estar habilitado no client. Um grant desconhecido recebe unsupported_grant_type; um conhecido que o client não habilitou recebe unauthorized_client.

Authorization codeBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/token \
  -u "acme-web:$CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  --data-urlencode redirect_uri=https://app.acme.com/callback \
  -d code_verifier="$CODE_VERIFIER"
Campo da respostaQuando
access_token, token_type, expires_inSempre. token_type é Bearer.
id_tokenQuando uma pessoa entra com o escopo openid; no refresh, quando o client está configurado para reemiti-lo.
refresh_token, refresh_expires_inQuando um refresh token é emitido.
scopeOs escopos concedidos.
issued_token_typeSó no token exchange.

Autorização de dispositivo

Inicia o fluxo de dispositivo (RFC 8628) para aparelhos com entrada limitada. O client se autentica como no endpoint de token e precisa ter o grant device code habilitado.

InícioBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/device/auth \
  -d client_id=acme-cli \
  --data-urlencode "scope=openid profile offline_access"
Campo da respostaValor
device_codeCom o que o aparelho consulta o endpoint de token.
user_codeOito caracteres no formato XXXX-XXXX, para a pessoa digitar.
verification_uri{emissor}/device, onde a pessoa digita o código.
verification_uri_completeA mesma página com o código preenchido, para um QR code.
expires_inSegundos até os códigos expirarem: 10 minutos.
intervalSegundos de espera entre as consultas: 5.

Enquanto a pessoa decide, a consulta responde authorization_pending; consultar rápido demais responde slow_down; depois de 10 minutos, expired_token; um pedido negado, access_denied. Veja Fluxo de dispositivo.

UserInfo

Devolve as claims atuais da pessoa por trás de um access token: sempre sub, mais as claims que os escopos profile, email e phone do token liberam, lidas na hora a cada chamada. Um token sem openid recebe 403 com insufficient_scope; um inválido, 401 com invalid_token, os dois com o cabeçalho WWW-Authenticate.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Introspecção

Diz a uma API se um token ainda está ativo (RFC 7662), inclusive revogação, sessão encerrada e usuário suspenso, que a conferência da assinatura sozinha não enxerga. Quem chama se autentica como client. A resposta é sempre 200: {"active": false} para qualquer token que não seja válido, sem dizer o motivo.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/introspect \
  -u "acme-web:$CLIENT_SECRET" \
  -d token="$ACCESS_TOKEN" \
  -d token_type_hint=access_token

Um token ativo devolve active, scope, client_id, username, token_type, exp, iat, nbf, sub, aud, iss e jti, mais claims de autorização como os papéis, acr, amr, sid e a organização. Com token_type_hint=api_key o client pergunta por uma das chaves de API dos seus consumers: uma chave ativa devolve sub (o consumer), client_id, scope, consumer_name, credential_id, credential_type e consumer_resource_access.

Revogação

Invalida um token de que você não precisa mais (RFC 7009), normalmente no logout. Quem chama se autentica como client, e toda requisição bem formada recebe 200, mesmo com um token desconhecido ou expirado. Revogar encerra a sessão por trás do token, o que também invalida os refresh tokens dela; a pessoa continua conectada às outras aplicações do realm.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/revoke \
  -u "acme-web:$CLIENT_SECRET" \
  -d token="$REFRESH_TOKEN" \
  -d token_type_hint=refresh_token

Logout

Desconecta a pessoa do realm (RP-Initiated Logout). Envie o navegador para cá com:

ParâmetroObservações
id_token_hintUm ID token que este realm emitiu; um expirado também é aceito. Sem um hint válido, nada é encerrado e a pessoa vê uma tela de confirmação.
client_idO client que está saindo; lido do hint quando omitido.
post_logout_redirect_uriPara onde ir depois. Só é seguido quando registrado no client, comparado exatamente como um redirect URI.
stateVolta inalterado.
ui_localesIdiomas preferidos para as telas.
Pedido de logoutTexto simples
https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/logout
  ?id_token_hint=ID_TOKEN
  &post_logout_redirect_uri=https%3A%2F%2Fapp.acme.com%2F
  &state=af0ifjsldkj

Os clients que registraram um URI de logout back-channel ou front-channel são avisados sempre que uma sessão deles termina — no logout, mas também quando um administrador a revoga ou o usuário é suspenso. Veja Sessões e SSO.

Outros endereços sob um realm

EndereçoPara que serve
/realms/{realm}/deviceA página onde as pessoas digitam o código do dispositivo — o verification_uri.
/realms/{realm}/broker/{alias}/callbackO redirect URI a registrar num provedor de identidade externo. Aceita GET e POST.
/realms/{realm}/connections/callbackO redirect URI a registrar num provedor de contas conectadas.
/realms/{realm}/clients/{client}/webauthn/...As cerimônias de passkey usadas pelas telas hospedadas.

Erros

Os endpoints de protocolo respondem erros com os campos do RFC 6749 §5.2, mais o error_code do próprio Authio, para cruzar um relato com os logs:

401 UnauthorizedJSON
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials. The provided client_secret is not valid.",
  "error_code": "InvalidClientCredentials"
}

Todos os valores de error e os códigos por trás deles estão em Códigos de erro.

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