keycloakのServer Metadataの変遷

# keycloakのServer Metadataの変遷

## はじめに

日立製作所の乗松隆志と申します。keycloakのServer Metadataの変遷について記します。

**Notes: 本投稿の内容は、公開情報を元に独自に解釈したものです。**

## Server Metadata

Server Metadataとして記載されるクレームは、RFCなど標準仕様で規定のあるものと、製品独自のものがあると考えます。

標準仕様で規定のあるものについて、大きくは2つに分けられると考えます。

* OAuth 2.0の認可サーバーとしてのServer Metadata
* OpenID ConnectのOpenID ProviderとしてのServer Metadata

keycloakのServer Metadataは、.well-known url(.well-known/openid-configuration)から取得します。

Server Metadataには、その製品がサポートしている機能などが記載されますが、それが全てではないことにご注意ください。

## 1.9.8.Final

2016/6/13に[リリース](http://blog.keycloak.org/2016/06/keycloak-198final-released.html)されました。

```
{
 "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",
 "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/master/clients-registrations/openid-connect"
}
```

13クレームあります。

|#|クレーム名|参照元|説明|
|:--|:--|:--|:--|
|1 |"issuer"| 参照文献[2]| keycloakの識別子です。|
|2|"authorization_endpoint"| 参照文献[2]|認可エンドポイントのURLです。|
|3|"token_endpoint"| 参照文献[2]|トークンエンドポイントのURLです。|
|4|"token_introspection_endpoint"|なし|トークンイントロスペクションエンドポイントのURLのようですが、<br>参照文献[2]で定義されているクレーム名(“introspection_endpoint")と異なっています。|
|5|"userinfo_endpoint"| 参照文献[3]|UserInfoエンポイントのURLです。|
|6|"end_session_endpoint"| 参照文献[4]|エンドユーザーのログアウト用エンドポイントのURLです。|
|7|"jwks_uri"| 参照文献[2]|keycloakが提供するJWK Set（鍵情報）の取得用エンドポイントのURLです。|
|8|"grant_types_supported"| 参照文献[2]|keycloakがサポートしているOAuth 2.0のGrant Typeのリストです。|
|9|"response_types_supported"| 参照文献[2]|keycloakがサポートしているOAuth 2.0の”response_type”の値のリストです。|
|10|"subject_types_supported"| 参照文献[3]|keycloakがサポートしているSubject Identifierの種別のリストです。|
|11|"id_token_signing_alg_values_supported"| 参照文献[3]|keycloakがサポートしている、IDトークンに対するJWSによる署名アルゴリズムのリストです。|
|12|"response_modes_supported"| 参照文献[2]|keycloakがサポートしているOAuth 2.0の”response_mode”の値のリストです。|
|13|"registration_endpoint"| 参照文献[2]|keycloakにクライアントを登録するために使用される<br>OAuth 2.0 Dynamic Client Registration EndpointのURLです。|

## 2.5.5.Final

2017/3/15に[リリース](http://blog.keycloak.org/2017/03/keycloak-255final-released.html)されました。

```
{
 "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":["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://localhost:8080/auth/realms/master/clients-registrations/openid-connect",
 "token_endpoint_auth_methods_supported":["private_key_jwt","client_secret_basic","client_secret_post"],
 "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","offline_access"],
 "request_parameter_supported":true,
 "request_uri_parameter_supported":true
}

```

以下11クレームが追加され、計24クレームとなりました。

|#|クレーム名|参照元|説明|
|:--|:--|:--|:--|
|1|"check_session_iframe"|参照文献[4]|RP(Relying Party)がOP(OpenID Provider)とエンドユーザーのセッション情報の通信を行う際に使用するエンドポイントのURLです。<br>keycloakがOPにあたり、クライアントがRPにあたります。|
|2|"userinfo_signing_alg_values_supported"|参照文献[3]|UserInfoエンドポイントからの応答データに対するJWSによる署名アルゴリズムについて、<br>keycloakがサポートしているもののリストです。|
|3|"request_object_signing_alg_values_supported"|参照文献[3]|リクエストオブジェクトに対するJWSによる署名アルゴリズムについて、<br>keycloakがサポートしているもののリストです。|
|4|"token_endpoint_auth_methods_supported"|参照文献[2]|keycloakのトークンエンドポイントがサポートしている、クライアントの認証方式のリストです。|
|5|"token_endpoint_auth_signing_alg_values_supported"|参照文献[2]|keycloakトークンエンドポイントがサポートするクライアントの認証方式のうち、<br>JWTへのJWSによる署名を使用する方式である"private_key_jwt"と"client_secret_jwt"について、<br>認可サーバーがサポートする署名アルゴリズムのリストです。|
|6|"claims_supported"|参照文献[3]|keycloakがサポートしているクレームの名前のリストです（これらが全てであるというわけではありません）。|
|7|"claim_types_supported"|参照文献[3]|サポートしているクレームの種別です。|
|8|"claims_parameter_supported"|参照文献[3]|認可要求時のクエリパラメータとして、keycloakがclaimsをサポートするかどうかを真偽値で示すものです。|
|9|"scopes_supported"| 参照文献[2]|サポートしているスコープのリストです（これらが全てであるというわけではありません）。|
|10|"request_parameter_supported"|参照文献[3]|認可要求時のクエリパラメータとして、keycloakがrequestをサポートするかどうかを真偽値で示すものです。<br>リクエストオブジェクトのサポートに関連します。|
|11|"request_uri_parameter_supported"|参照文献[3]|認可要求時のクエリパラメータとして、keycloakがrequest_uriをサポートするかどうかを真偽値で示すものです。<br>リクエストオブジェクトのサポートに関連します。|

以下1クレームで、値の追加がありました。

|#|クレーム名|参照元|説明|
|:--|:--|:--|:--|
|1|"subject_types_supported"| 参照文献[3]|keycloakがサポートしているSubject Identifierの種別のリストです。<br>1.9.8.Finalでは、normalのみでしたが、2.5.5.Finalでは、pairwiseが追加されました。|

1.9.8.Finalからの変更点をかいつまんで言うと、以下のようになります。

* [OIDC] UserInfoエンドポイントからの応答データについて、JWAで規定されるRS256による署名のサポートを明示するようになりました。
* [OIDC] リクエストオブジェクトに施される署名について、JWAで規定されるnoneとRS256のサポートを明示するようになりました。
* [OIDC] トークンエンドポイントでのクライアントの認証方式として、OpenID Connect 1.0で規定される、"private_key_jwt","client_secret_basic","client_secret_post"のサポートを明示するようになりました。
* [OIDC] requestおよびrequest_uriクエリパラメータによるリクエストオブジェクトのサポートを明示するようになりました。
* [OIDC] Subject Identifierについて、pairwiseのサポートを明示するようになりました。


## 3.4.3.Final

2018/1/4に[リリース](http://blog.keycloak.org/2018/01/keycloak-343final-released.html)されました。

2.5.5.Finalとかわらずです。


## 4.5.0.Final

2018/9/26に[リリース](http://blog.keycloak.org/2018/09/keycloak-450final-released.html)されました。

```
{
 "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":["ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512"],
 "userinfo_signing_alg_values_supported":["ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512","none"],
 "request_object_signing_alg_values_supported":["none","RS256"],
 "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":["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","offline_access","phone","profile"],
 "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"
}
```

以下3クレームが追加され、計27クレームとなりました。

|#|クレーム名|参照元|説明|
|:--|:--|:--|:--|
|1|"code_challenge_methods_supported"|参照文献[2]|RFC 7636 Proof Key for Code Exchange (PKCE)で定義されているcode challengeの方式のうち、<br>keycloakがサポートしているもののリストです。|
|2|"tls_client_certificate_bound_access_tokens"|参照文献[5]|TLSにおける証明書を使用したクライアント認証を利用して、アクセストークンをHolder-of-Keyなトークンとする<br>機能をサポートしているかどうかを真偽値で示すものです。|
|3|"introspection_endpoint"|参照文献[2]|トークンイントロスペクションエンドポイントのURLです。<br>”token_introspection_endpoint”として1.9.8.Finalのころからあったものの、クレーム名が間違っていた模様です。|

以下4クレームで、値の追加がありました。

|#|クレーム名|参照元|説明|
|:--|:--|:--|:--|
|1|"id_token_signing_alg_values_supported"|参照文献[3]|keycloakがサポートしている、IDトークンに対するJWSによる署名アルゴリズムのリストです。これまでは“RS256”のみのサポートでしたが、<br>新たに”RS384”、”RS512”、”ES256”、”ES384”、”ES512”、”HS256”、”HS384”、”HS512”がサポートされるようになりました。|
|2|"userinfo_signing_alg_values_supported"|参照文献[3]|UserInfoエンドポイントからの応答データに対するJWSによる署名アルゴリズムについて、keycloakがサポートしているもののリストです。<br>これまでは“RS256”のみのサポートでしたが、新たに”RS384”、”RS512”、”ES256”、”ES384”、”ES512”、”HS256”、”HS384”、”HS512”、”none”<br>がサポートされるようになりました。|
|3|"token_endpoint_auth_methods_supported"|参照文献[2]|keycloakのトークンエンドポイントがサポートしている、クライアントの認証方式のリストです。<br>これまで"private_key_jwt","client_secret_basic","client_secret_post"がサポートされていましたが、<br>新たに"client_secret_jwt"がサポートされるようになりました。|
|4|"scopes_supported"|参照文献[2]|サポートしているスコープのリストです（これらが全てであるというわけではありません）。<br>これまでは"openid","offline_access"がサポートされていましたが、<br>新たに"address","email","phone","profile"がサポートされるようになりました。|

3.4.3.Finalからの変更点をかいつまんで言うと、以下のようになります。

* [OAuth 2.0] PKCEをサポートし、方式として、"plain"と"S256"に対応できるようになりました。
* [OAuth 2.0] TLSにおける証明書を使用したクライアント認証を利用して、アクセストークンをHolder-of-Keyなトークンとする機能をサポートするようになりました。
* [OAuth 2.0] トークンイントロスペクションのURLについて、クレーム名が間違っていたようなので、正しいクレーム名で追加されました。
* [OIDC] IDトークンの署名アルゴリズムとして、"ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512"もサポートできるようになりました。(もともとはRS256のみ)
* [OIDC] UserInfoエンドポイントの応答に入れる署名アルゴリズムとして、"ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512","none"もサポートできるようになりました。(もともとはRS256のみ)
* [OIDC] トークンエンドポイントでのクライアント認証方法として、"private_key_jwt","client_secret_basic","client_secret_post","client_secret_jwt"の4つをサポートできるようになりました。("client_secret_jwt"が加わった)

## 参照文献

\[1\] [OAuth Parameters](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml)

IANAのRegistryに登録済みの、OAuth 2.0に関する各種パラメータの一覧です。

\[2\] [OAuth 2.0 Authorization Server Metadata](https://tools.ietf.org/html/rfc8414#section-2)

OAuth 2.0の認可サーバーのメタデータの定義です。

\[3\] [OpenID Connect Discovery 1.0 - 3. OpenID Provider Metadata](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata)

OpenID Providerのメタデータの定義です。

\[4\] [OpenID Connect Session Management 1.0](https://openid.net/specs/openid-connect-session-1_0.html#OPMetadata)

OIDCのセッションの管理に関する、OpenID Providerのメタデータの定義です。

\[5\] [OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens](https://tools.ietf.org/html/draft-ietf-oauth-mtls-12)

TLSにおける証明書を使用したクライアント認証を利用して、アクセストークンをHolder-of-Keyなトークンにする方法を記したものです。