Keycloak 的 OAuth2 / OpenID Connect 端点是什么?

What are Keycloak's OAuth2 / OpenID Connect endpoints?

我们正在尝试将 Keycloak 作为一种 SSO 解决方案进行评估,它在很多方面看起来都不错,但文档在基础知识方面非常缺乏。

对于 http://localhost:8080/ 领域 test 上的给定 Keycloak 安装,OAuth2 Authorization Endpoint, OAuth2 Token Endpoint and OpenID Connect UserInfo Endpoint 是什么?

我们对使用 Keycloak 自己的客户端库不感兴趣,我们想使用标准的 OAuth2 / OpenID Connect 客户端库,因为使用 keycloak 服务器的客户端应用程序将以多种语言编写(PHP、Ruby、节点、Java、C#、Angular)。因此,使用 Keycloak 客户端的示例对我们没有用。

经过大量挖掘,我们或多或少地抓取了信息(主要来自 Keycloak 自己的 JS 客户端库):

  • 授权端点: /auth/realms/{realm}/tokens/login
  • 令牌端点: /auth/realms/{realm}/tokens/access/codes

至于 OpenID Connect UserInfo,目前 (1.1.0.Final) Keycloak 未实现此端点,因此它不完全符合 OpenID Connect 标准。但是,已经有一个 patch 添加了在撰写本文时应包含在 1.2.x.

- 具有讽刺意味的是,Keycloak 确实发回了一个 id_token 和访问令牌。 id_tokenaccess_token都是signed JWTs,token的key是OpenID Connect的key,即:

"iss":  "{realm}"
"sub":  "5bf30443-0cf7-4d31-b204-efd11a432659"
"name": "Amir Abiri"
"email: "..."

因此,虽然 Keycloak 1.1.x 不完全兼容 OpenID Connect,但它在 OpenID Connect 语言中 "speak"。

对于 Keycloak 1.2,可以通过 url

检索上述信息
http://keycloakhost:keycloakport/auth/realms/{realm}/.well-known/openid-configuration

例如,如果域名是 demo:

http://keycloakhost:keycloakport/auth/realms/demo/.well-known/openid-configuration

上面的示例输出 url:

{
    "issuer": "http://localhost:8080/auth/realms/demo",
    "authorization_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/auth",
    "token_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token",
    "userinfo_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/userinfo",
    "end_session_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/logout",
    "jwks_uri": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/certs",
    "grant_types_supported": [
        "authorization_code",
        "refresh_token",
        "password"
    ],
    "response_types_supported": [
        "code"
    ],
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],
    "response_modes_supported": [
        "query"
    ]
}

https://issues.jboss.org/browse/KEYCLOAK-571

找到信息

注意:您可能需要将您的客户端添加到有效重定向 URI 列表

在版本 1.9.0 json 中,所有端点都位于地址 /auth/realms/{realm}

  • 授权端点: /auth/realms/{realm}/account
  • 令牌端点: /auth/realms/{realm}/protocol/openid-connect

在 1.9.3.Final 版本中,Keycloak 有许多可用的 OpenID 端点。这些可以在 /auth/realms/{realm}/.well-known/openid-configuration 找到。假设您的领域名为 demo,该端点将产生类似于此的 JSON 响应。

{
  "issuer": "http://localhost:8080/auth/realms/demo",
  "authorization_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/auth",
  "token_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token",
  "token_introspection_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token/introspect",
  "userinfo_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/userinfo",
  "end_session_endpoint": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/logout",
  "jwks_uri": "http://localhost:8080/auth/realms/demo/protocol/openid-connect/certs",
  "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"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "registration_endpoint": "http://localhost:8080/auth/realms/demo/clients-registrations/openid-connect"
}

据我所知,这些端点实现了 Oauth 2.0 规范。

FQDN/auth/realms/{realm_name}/.well-known/openid-configuration

你会在这里看到所有内容,如果身份提供者也是 Keycloak,那么提供这个 URL 将设置所有其他身份提供者,如果他们支持并且他们已经处理它

密钥斗篷版本:4.6.0

  • TokenUrl: [域]/auth/realms/{REALM_NAME}/protocol/openid-connect/token
  • AuthUrl:[域]/auth/realms/{REALM_NAME}/protocol/openid-connect/auth

实际上 link 到 .well-know 在您的领域设置的第一个选项卡上 - 但 link 看起来不像 link,而是文本框的值... 糟糕的 ui 设计。 Screenshot of Realm's General Tab

以下 link 提供 JSON 文档描述有关 Keycloak

的元数据
/auth/realms/{realm-name}/.well-known/openid-configuration

master 领域

的 Keycloak 6.0.1 报告了以下信息
{  
   "issuer":"http://localhost:8080/auth/realms/master",
   "authorization_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/auth",
   "token_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/token",
   "token_introspection_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/token/introspect",
   "userinfo_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/userinfo",
   "end_session_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/logout",
   "jwks_uri":"http://localhost:8080/auth/realms/master/protocol/openid-connect/certs",
   "check_session_iframe":"http://localhost:8080/auth/realms/master/protocol/openid-connect/login-status-iframe.html",
   "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":[  
      "PS384",
      "ES384",
      "RS384",
      "HS256",
      "HS512",
      "ES256",
      "RS256",
      "HS384",
      "ES512",
      "PS256",
      "PS512",
      "RS512"
   ],
   "userinfo_signing_alg_values_supported":[  
      "PS384",
      "ES384",
      "RS384",
      "HS256",
      "HS512",
      "ES256",
      "RS256",
      "HS384",
      "ES512",
      "PS256",
      "PS512",
      "RS512",
      "none"
   ],
   "request_object_signing_alg_values_supported":[  
      "PS384",
      "ES384",
      "RS384",
      "ES256",
      "RS256",
      "ES512",
      "PS256",
      "PS512",
      "RS512",
      "none"
   ],
   "response_modes_supported":[  
      "query",
      "fragment",
      "form_post"
   ],
   "registration_endpoint":"http://localhost:8080/auth/realms/master/clients-registrations/openid-connect",
   "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":[  
      "aud",
      "sub",
      "iss",
      "auth_time",
      "name",
      "given_name",
      "family_name",
      "preferred_username",
      "email"
   ],
   "claim_types_supported":[  
      "normal"
   ],
   "claims_parameter_supported":false,
   "scopes_supported":[  
      "openid",
      "address",
      "email",
      "microprofile-jwt",
      "offline_access",
      "phone",
      "profile",
      "roles",
      "web-origins"
   ],
   "request_parameter_supported":true,
   "request_uri_parameter_supported":true,
   "code_challenge_methods_supported":[  
      "plain",
      "S256"
   ],
   "tls_client_certificate_bound_access_tokens":true,
   "introspection_endpoint":"http://localhost:8080/auth/realms/master/protocol/openid-connect/token/introspect"
}

您还可以通过进入管理控制台 -> 领域设置 -> 单击端点字段上的超链接来查看此信息。

我目前正在试用 Keycloak 18.0.0,我发现“/auth”部分已从 OIDC 发现中删除 URL:

https://{keycloakhost}:{keycloakport}/realms/{realm}/.well-known/openid-configuration

这个 returns 一个 JSON 包含端点的数据结构:

{
  "issuer": "https://{keycloakhost}:{keycloakport}/realms/{realm}",
  "authorization_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/auth",
  "token_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/token",
  "introspection_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/token/introspect",
  "userinfo_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/userinfo",
  "end_session_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/logout",
  "frontchannel_logout_session_supported": true,
  "frontchannel_logout_supported": true,
  "jwks_uri": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/certs",
  "check_session_iframe": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/login-status-iframe.html",
  "grant_types_supported": [
    "authorization_code",
    "implicit",
    "refresh_token",
    "password",
    "client_credentials",
    "urn:ietf:params:oauth:grant-type: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"
  ],
  "id_token_encryption_alg_values_supported": [
    "RSA-OAEP",
    "RSA-OAEP-256",
    "RSA1_5"
  ],
  "id_token_encryption_enc_values_supported": [
    "A256GCM",
    "A192GCM",
    "A128GCM",
    "A128CBC-HS256",
    "A192CBC-HS384",
    "A256CBC-HS512"
  ],
  "userinfo_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512",
    "none"
  ],
  "request_object_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512",
    "none"
  ],
  "request_object_encryption_alg_values_supported": [
    "RSA-OAEP",
    "RSA-OAEP-256",
    "RSA1_5"
  ],
  "request_object_encryption_enc_values_supported": [
    "A256GCM",
    "A192GCM",
    "A128GCM",
    "A128CBC-HS256",
    "A192CBC-HS384",
    "A256CBC-HS512"
  ],
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post",
    "query.jwt",
    "fragment.jwt",
    "form_post.jwt",
    "jwt"
  ],
  "registration_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/clients-registrations/openid-connect",
  "token_endpoint_auth_methods_supported": [
    "private_key_jwt",
    "client_secret_basic",
    "client_secret_post",
    "tls_client_auth",
    "client_secret_jwt"
  ],
  "token_endpoint_auth_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512"
  ],
  "introspection_endpoint_auth_methods_supported": [
    "private_key_jwt",
    "client_secret_basic",
    "client_secret_post",
    "tls_client_auth",
    "client_secret_jwt"
  ],
  "introspection_endpoint_auth_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512"
  ],
  "authorization_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512"
  ],
  "authorization_encryption_alg_values_supported": [
    "RSA-OAEP",
    "RSA-OAEP-256",
    "RSA1_5"
  ],
  "authorization_encryption_enc_values_supported": [
    "A256GCM",
    "A192GCM",
    "A128GCM",
    "A128CBC-HS256",
    "A192CBC-HS384",
    "A256CBC-HS512"
  ],
  "claims_supported": [
    "aud",
    "sub",
    "iss",
    "auth_time",
    "name",
    "given_name",
    "family_name",
    "preferred_username",
    "email",
    "acr"
  ],
  "claim_types_supported": [
    "normal"
  ],
  "claims_parameter_supported": true,
  "scopes_supported": [
    "openid",
    "phone",
    "roles",
    "microprofile-jwt",
    "email",
    "web-origins",
    "offline_access",
    "address",
    "profile"
  ],
  "request_parameter_supported": true,
  "request_uri_parameter_supported": true,
  "require_request_uri_registration": true,
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ],
  "tls_client_certificate_bound_access_tokens": true,
  "revocation_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/revoke",
  "revocation_endpoint_auth_methods_supported": [
    "private_key_jwt",
    "client_secret_basic",
    "client_secret_post",
    "tls_client_auth",
    "client_secret_jwt"
  ],
  "revocation_endpoint_auth_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "HS256",
    "HS512",
    "ES256",
    "RS256",
    "HS384",
    "ES512",
    "PS256",
    "PS512",
    "RS512"
  ],
  "backchannel_logout_supported": true,
  "backchannel_logout_session_supported": true,
  "device_authorization_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/auth/device",
  "backchannel_token_delivery_modes_supported": [
    "poll",
    "ping"
  ],
  "backchannel_authentication_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/ext/ciba/auth",
  "backchannel_authentication_request_signing_alg_values_supported": [
    "PS384",
    "ES384",
    "RS384",
    "ES256",
    "RS256",
    "ES512",
    "PS256",
    "PS512",
    "RS512"
  ],
  "require_pushed_authorization_requests": false,
  "pushed_authorization_request_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/ext/par/request",
  "mtls_endpoint_aliases": {
    "token_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/token",
    "revocation_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/revoke",
    "introspection_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/token/introspect",
    "device_authorization_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/auth/device",
    "registration_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/clients-registrations/openid-connect",
    "userinfo_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/userinfo",
    "pushed_authorization_request_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/ext/par/request",
    "backchannel_authentication_endpoint": "https://{keycloakhost}:{keycloakport}/realms/{realm}/protocol/openid-connect/ext/ciba/auth"
  }
}