Hello Keycloak Team,
whilst comparing the output of googles .well-known/openid-configuration
with that of Keycloak
I noticed that the .well-known/openid-configuration endpoint in Keycloak
does not expose a "revocation_endpoint".
See below...
I just stumbled upon the old keycloak-dev ML thread where this was
mentioned already.
http://lists.jboss.org/pipermail/keycloak-dev/2016-April/007054.html
Are there any plans to support token revocation with a
`revocation_endpoint`?
RFC7009 mentions that an implementation MUST provide token revocation for
refresh_tokens
and SHOULD provide support for access_tokens, perhaps only supporting
refresh_tokens would be a good start.
It seems that token revocation is currently handled by updating the
"notBefore" timestamp
of a realm and ensuring that only tokens with issuedAt timestamp >
notBefore are considered valid.
A naive way of supporting the revocation_endpoint could just be to update
the realms notBefore timestamp.
However I think this might be a bit too coarse-grained since it might
invalidate a bunch of tokens at once,
which could potentially require many/all clients/users to request new
tokens.
A more fine-grained approach could be to record the hash of a revoked
refresh_token value in a
database table like revoked_tokens (id, token_hash, issued_at, token_type).
When a new token is requested with a refresh_token, then one could try to
lookup an entry in the
revoked_tokens table with the token_hash of the current token.
If nothing was found then the token was not revoked and can be used.
Otherwise, the token was revoked and no new
tokens should be issued with the given refresh_token, which means that the
user / client must reauthenticate again.
Table entries could be cleared once the associated refresh tokens have
timed out.
OAuth2 Token Revocation Overview:
https://connect2id.com/blog/token-revocation
OAuth2 Token Revocation RFC:
https://tools.ietf.org/html/rfc7009
Cheers,
Thomas
This is the output of googles .well-known/openid-configuration endpoint:
https://accounts.google.com/.well-known/openid-configuration
{
"issuer": "https://accounts.google.com",
"authorization_endpoint":
"https://accounts.google.com/o/oauth2/v2/auth
",
"token_endpoint": "https://www.googleapis.com/oauth2/v4/token",
"userinfo_endpoint":
"https://www.googleapis.com/oauth2/v3/userinfo",
"revocation_endpoint":
"https://accounts.google.com/o/oauth2/revoke",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
]
}
This is the output of Keycloaks .well-known/openid-configuration endpoint
(Keycloak 4.1.0.Final)
http://iam.tdlabs.local:8080/auth/realms/concourseci/.well-known/openid-c...
{
"issuer": "http://iam.tdlabs.local:8080/auth/realms/concourseci",
"authorization_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"token_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"token_introspection_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"userinfo_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"end_session_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"jwks_uri": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"check_session_iframe": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/protocol/openid-conn...
",
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"password",
"client_credentials"
],
"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": [
"RS256"
],
"userinfo_signing_alg_values_supported": [
"RS256"
],
"request_object_signing_alg_values_supported": [
"none",
"RS256"
],
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"registration_endpoint": "
http://iam.tdlabs.local:8080/auth/realms/concourseci/clients-registration...
",
"token_endpoint_auth_methods_supported": [
"private_key_jwt",
"client_secret_basic",
"client_secret_post",
"client_secret_jwt"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256"
],
"claims_supported": [
"sub",
"iss",
"auth_time",
"name",
"given_name",
"family_name",
"preferred_username",
"email"
],
"claim_types_supported": [
"normal"
],
"claims_parameter_supported": false,
"scopes_supported": [
"openid",
"address",
"concourse.main",
"email",
"offline_access",
"phone",
"profile",
"read"
],
"request_parameter_supported": true,
"request_uri_parameter_supported": true,
"code_challenge_methods_supported": [
"plain",
"S256"
],
"tls_client_certificate_bound_access_tokens": true
}