JWKsエンドポイント
-
id_tokenの署名を検証するための公開鍵のmodulus(絶対値)とexponent(指数値)を返却するエンドポイント- JSON Web Key (JWK):署名鍵を表現するためのJSONデータ構造
リクエスト
- Keycloak例
GET /auth/realms/master/protocol/openid-connect/certs HTTP/1.1
Host: localhost:8080
レスポンス
- Keycloak例
{
"keys": [
{
"kid": "QSiaBQwkRZ9vqJgGv2byfTppJyeJT9mkxENgbxttoT8",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "jKv0hkM...b9VvYIJ9hG8xN6zOQ",
"e": "AQAB",
"x5c": [
"MIIC.....DyPe2E="
],
"x5t": "9MMflCR5h-VY2D4HZx_kZ_L64XM",
"x5t#S256": "DOiv2PKlM9QyI97gyUGl_95EULW9kyrv1ocAbxn1Q6M"
},
{
"kid": "oYNqQTimc0dJfz7JFKNCwqgWC5Fp26eidiNcva6Nfn8",
"kty": "RSA",
"alg": "RS256",
"use": "enc",
"n": "mJNKSuJ...69NGCQ",
"e": "AQAB",
"x5c": [
"MIICmzCCAYMCBgF8.../S2ZUocM="
],
"x5t": "s7q4K84XS_OT4kRhwY-dPBGDeQU",
"x5t#S256": "NbJVyOEgN_P5tJ0AO8bKX8vK2Loaw1PSQrlSS3YMhc4"
}
]
}
パラメータ
| パラメーター名 | 説明 |
|---|---|
| keys | JWK配列 |
| kid | 鍵識別子 ID TokenのHeaderに含まれているKey ID。 署名に利用した秘密鍵の対になる公開鍵を判定するために利用。 |
| kty | RSAやEC等の暗号アルゴリズムファミリー |
| use | 公開鍵の用途 |
| alg | 署名検証アルゴリズム |
| x5c | PKIX証明書からなるJSON 配列 それぞれの証明書文字列は base64 エンコードされた値で表現される※base64url エンコードではない 当該JWK の鍵を含む PKIX 証明書は先頭の証明書である必要がある |
| x5t | DER エンコードされた X.509 証明書の SHA-1 thumbprintの base64url エンコード値 当該証明書に含まれる鍵は当該 JWK の示す公開鍵と一致する |
| x5t#S256 | DER エンコードされた X.509 証明書の SHA-256 thumbprint の base64url エンコード値 当該証明書に含まれる鍵は当該 JWK の示す公開鍵と一致する |
| n | modulus 公開鍵を復元するための公開鍵の絶対値 |
| e | exponent 公開鍵を復元するための指数値 |
id_token署名検証の流れ
-
id_tokenを取得 -
id_tokenをパース -
id_tokenからalg、kidを取得 - JWKsエンドポイントへリクエストして公開鍵を取得
- 4で取得したkeys配列にある
kidと3で取得したkidが一致するものを取得 -
kidと対応するnとeも取得 -
nとe、algを利用して公開鍵を作成 - 7で作成した鍵を使用して
id_tokenを検証
-
PyJWTを用いてid_token検証を行う例
import jwt
from jwt import PyJWKClient
def get_payload_from_id_token(id_token):
# Keycloak JWKs Endpoint URL
url = f"{KEYCLOAK_BASE_URL_CONTAINER_NAME}auth/realms/{KEYCLOAK_REALM_NAME}/protocol/openid-connect/certs"
# JWKs Endpoint Client
jwks_client = PyJWKClient(url)
# Signing Key
signing_key = jwks_client.get_signing_key_from_jwt(id_token)
# Decoding id_token by Signing Key
payload = jwt.decode(id_token, signing_key.key, algorithms=["RS256"],audience=APP_CLIENT_ID)
return payload