OpenID Connect Discovery¶
El endpoint de Discovery (.well-known/openid-configuration) publica la configuración completa del servidor OpenID Connect. Los clientes usan este endpoint para descubrir automáticamente los endpoints de autorización, token, JWKS y UserInfo sin necesidad de configuración manual.
URL en Keycloak¶
Por realm:
https://{KC_HOSTNAME}/realms/{realm-name}/.well-known/openid-configuration
Ejemplos:
https://auth.example.com/realms/realm-internal/.well-known/openid-configuration
https://auth.example.com/realms/realm-partners/.well-known/openid-configuration
Consultar el discovery endpoint¶
Campos más importantes de la respuesta¶
{
"issuer": "https://auth.example.com/realms/realm-internal",
"authorization_endpoint": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/auth",
"token_endpoint": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/token",
"introspection_endpoint": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/userinfo",
"end_session_endpoint": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/logout",
"jwks_uri": "https://auth.example.com/realms/realm-internal/protocol/openid-connect/certs",
"grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials", "device_code", "urn:openid:params:grant-type:ciba"],
"response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
"subject_types_supported": ["public", "pairwise"],
"id_token_signing_alg_values_supported": ["PS384", "ES384", "RS384", "HS256", "HS512", "ES256", "RS256", "HS384", "ES512", "PS256", "PS512", "RS512"],
"token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post", "tls_client_auth", "client_secret_jwt"],
"claims_supported": ["aud", "sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email", "acr"],
"code_challenge_methods_supported": ["plain", "S256"]
}
Campos clave¶
| Campo | Descripción | Uso |
|---|---|---|
issuer |
Identificador del servidor de autorización | Se valida en el claim iss de cada JWT |
authorization_endpoint |
URL del flujo de autorización | Redirigir al usuario para login |
token_endpoint |
Intercambio de código por tokens | POST para obtener access/refresh/id tokens |
jwks_uri |
URI de las claves públicas (JWKS) | Descarga de claves para verificar firma JWT |
userinfo_endpoint |
Perfil del usuario autenticado | Obtener claims adicionales del usuario |
end_session_endpoint |
Logout del usuario | Cerrar sesión en Keycloak |
introspection_endpoint |
Verificar un opaque token | No necesario con JWT (auto-validable) |
code_challenge_methods_supported |
Métodos PKCE soportados | Confirmar que S256 está disponible |
Uso en Spring Security¶
Spring Security descarga automáticamente la configuración desde el issuer URI:
# application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
# Spring descarga {issuer-uri}/.well-known/openid-configuration
# y usa jwks_uri automáticamente
issuer-uri: https://auth.example.com/realms/realm-internal
Esto elimina la necesidad de configurar jwk-set-uri manualmente. Spring Security también usa el issuer del discovery para validar el claim iss de cada JWT recibido.
Cache del discovery endpoint
Spring Security cachea la respuesta del discovery endpoint en memoria. Si rotas las claves de firma en Keycloak, el servicio descargará las nuevas JWKs automáticamente cuando reciba un JWT con un kid desconocido. No es necesario reiniciar el servicio.
Latencia al arrancar
En el arranque, Spring Security hace una petición HTTP al discovery endpoint y al JWKS URI de Keycloak. Si Keycloak tarda en estar disponible (p. ej. en docker compose up), el servicio puede fallar el health check inicial. Configura depends_on y condition: service_healthy en compose.yml.