KeycloakでのOpenID Connectお勉強メモ #2
はじめに
#1 からのつづきです。前回はこのフローを作りました。
今回はこの内容を詳しく見ていきます。
フロー図
Flow_OIDC
参考文献
調べていくにあたり以下の資料を見ながら進めて行きます。
- OpenID Connect Core 1.0 日本語訳
- OpenID Connect Basic Client Implementer's Guide 1.0 日本語訳
- OpenID Connect Discovery 1.0
OpenID Connect フローには種類があるということを知る
OpenID Connect Basic Client Implementer's Guide 1.0 日本語訳 - 2. Protocol Elementsに書いてあるように OpenID Connect には以下の種類があります。
- Authorization Code Flow
- Implicit Flow
- Hybrid Flow
ここでは Authorization Code Flow (最も一般的な方法) でやっています。
まずはこれを見ときます。
OpenID Connect Basic Client Implementer's Guide 1.0 日本語訳 - 2.1. Code Flow
Code Flow は以下のステップからなる.
- Client は必要なリクエストパラメータを含んだ Authentication Request を構築する.
- Client は Authorization Server にリクエストを送信する.
- Authorization Server は End-User を認証する.
- Authorization Server は End-User の Consent/Authorization を取得する.
- Authorization Server は End-User を
code
とともに Client に戻す.- Client は
code
を Token Endpoint に送信し, Access Token と ID Token を受け取る.- Client はそれらのトークンを検証し, End-User の Subject Identifier を取得する.
おおざっぱに構成を理解する
-page-1
End-User
ブラウザを操作する人
Relying Party (RP)
OpenID Connect を利用する側
-
Apache + mod-auth-openidc
-
PHP 公式のDockerコンテナを使う
- apache2が入っている
- libapache2-mod-auth-openidcも入れます
- 詳細は Dockerfile 参照
-
libapache2-mod-auth-openidc
- Apacheのモジュール(アドオンみたいなもの?)でこれを付けるとApacheがOpenID Connectで話せるようになる便利なもの
- Protected Resource を定義するだけでOPに問い合わせてくれます
- 今回の場合
/secure
以下のリソースを Protected Resource にしてこのリソースにリクエストがあれば Keycloak に問い合わせするようになります。
-
サイトの構成は以下の通り
/ ├── index.html --- TOP 画面 ├── loggedout.html --- ログアウト後の画面 └── secure (Protedted Resource) └── welcome.php --- ログイン後の画面
OpenID Provider (OP)
OpenID Connect を提供する側
-
Keycloak
-
操作者(End-User)の Account(アカウント) を保持する
- Account は
UserInfo
とCredential
で構成される- UserInfo - 名前とかメールアドレスとか
- Credential - パスワード
- Account は
-
RP-Apache(mod-auth-openidc) からリダイレクトされてEnd-userの認証認可を行う
-
RP-Apache(mod-auth-openidc) からのリクエストでEnd-userのUserInfoを提供する
画面フロー
-
- ブラウザから
index.html
にアクセスしてTOP画面を表示する
- ブラウザから
-
-
Login with Keycloak
をクリックすると/secure/welcome.php
に遷移する
-
-
- が、しかし
/secure
は mod-auth-openidc が管理する Protected Resource なのである
- が、しかし
-
- mod-auth-openidc はすかさず Keycloak にリダイレクトする
-
- Keycloak はログイン画面を表示する
-
- 無事ログインできたら Welcome画面(
/secure/welcome.php
)を画面に表示する
- 無事ログインできたら Welcome画面(
-
- welcome画面で
Logout
をクリックするとログアウト処理をして ログアウト完了画面に遷移する
- welcome画面で
-
- ログアウト完了画面で
Goto Top
をクリックするとTOP画面に戻る
- ログアウト完了画面で
memo : 今回は 7) 8)の詳細は調査していません、次の記事で...
Screen_Diagram
Keycloakのエンドポイント
フロー図に書いているエンドポイント
Configuration Endpoint
- OpenID Connect Discovery 1.0 - 4. Obtaining OpenID Provider Configuration Information
- OpenID Configuration (Keycloakが実装しているエンドポイント情報)
Authorization Endpoint(認可エンドポイント)
- OpenID Connect Core 1.0 - 3.1.2. Authorization Endpoint
- 認証画面出してID/パスワードを検証するところ
Authenticate Endpoint
- End-Userが提示したCredentialを検証するエンドポイント
- ここで Credential の検証OKとなるとAuthorization Code(認可コード) を発行して End-User に返す
- OpenID Connectで明確に定義されたエンドポイントではなく、Authorization Endpointが提供する機能の一部という扱い
-
OpenID Connect Core 1.0 - 3.1.2.3. Authorization Server Authenticates End-User あたりの説明が参考になる
- ↑に書いてあるとおり End-User の認証方式については規定範疇外 となっていて認証のやり方の細かい方法は書いていないです。このへんが OpenID Connect と FIDO は補完関係 ということなんですね。
Token Endpoint(トークンエンドポイント)
- OpenID Connect Core 1.0 - 3.1.3. Token Endpoint
- Authorization Code(認可コード) を受け取って検証してOKであれば Access Token(アクセストークン) , ID Token(IDトークン) を発行して RP に返す
jwks_uri(証明書エンドポイント)
- OpenID Connect Discovery 1.0 - 3. OpenID Provider Metadata
- JWK Set を公開するエンドポイント
- 要はJWTの署名を検証するための公開鍵リポジトリということみたい
UserInfo Endpoint(ユーザー情報エンドポイント)
- OpenID Connect Core 1.0 - 5.3.1. UserInfo Request
- Access Token(アクセストークン) をパラメータで受けてユーザー情報を返す
フローの詳細
0. Start
ログインを開始するまでのフロー
- ブラウザ(End-user)が RP の 管理するリソース
index.html
にアクセスする
-page-2
-
index.html
は ログインする前に表示する画面(Protected Resouce ではない)なので、そのまま200 OK
でレスポンスを返す
test-oidc-rp_1.png
1. Login
Keycloakのログイン画面を表示するまでのフロー
-
Login with Keycloak
をクリックすると、./secure/welcome.php
に遷移(GET)する
-page-2_1
-
リクエストを受けたRPの
mod-auth-openidc
は 認証が必要なリソースであることを検知するmemo : 認可が必要なリソースの定義は
auth_openidc.conf
の<Location /secure>
でされている -
mod-auth-openidc
はまだアクセストークンを持っていないため、Keycloakからアクセストークンを取得するフローを開始するmemo : アクセストークンの取得フローが
openid-connect
であることはauth_openidc.conf
で設定されている
-
mod-auth-openidc
はまずKeyCloakからOpenID Configuration を取得するmemo : OpenID Configurationのエンドポイントは
auth_openidc.conf
で定義されている
-page-3
-
mod-auth-openidc
は End-user へレスポンス 302 Found(リダイレクト) を返す
レスポンスは以下の通り
パラメータ | 値 | 説明 | 取得元 |
---|---|---|---|
Location | /protocol/openid-connect/auth | 認可エンドポイント にリダイレクトすることを指定する |
OpenID Configuration の authorization_endpoint
|
response_type | code | トークン発行手順がcodeであることを示す |
auth_openidc.conf の OIDCResponseType
|
scope | openid | ID トークンの発行を要求することを示す |
auth_openidc.conf の OIDCClientID
|
client_id | test | KeyCloakで設定されているクライアント |
auth_openidc.conf の OIDCScope
|
redirect_uri | http://test-oidc-rp:8081/secure | Keycoakで認証が完了した後にリダイレクトさせてほしい場所。 ここからはKeycloakの制御になって操作を行うがその後にRPに戻ってきてほしいんでここで指定しておく(*1) |
auth_openidc.conf の OIDCRedirectURI
|
memo : state/nonceもついているけど省略
-
End-user は レスポンスを受け取り、KeyCloak の 認可エンドポイント にすっ飛んで行く
GET /auth/realms/master/protocol/openid-connect/auth ?response_type=code &scope=openid &client_id=test &state=28bO9uWjEJxcWw-W-k4J2VEmXYw &redirect_uri=http%3A%2F%2Ftest-oidc-rp%3A8081%2Fsecure &nonce=0Q3u5PmRIscEEgnIUeRiT9D8fI7HmwTQFd2dZ8Pk7aI
-page-4
-
Keycloak は ログイン画面を返す
memo : Cookieが大量についてくるけど省略
-page-5
Sign_in_to_Keycloak
2. Get Authorization Code
Username/Passwordを取得してから**Authorization Code(認可コード)**を取得するまでのフロー
memo
操作者がログイン画面でUsername/Passwordを入力して Sign In ボタンをクリックするところから始まります。
ここから先がゴチャゴチャしているんですがフローはノンストップなので操作者にとっては一瞬です。
-
ログイン画面でUsername/Passwordを入力して
Sign In
すると End-user は KeyCloak の Authenticate Endpoint に POST するmemo : クエリパラメータでめっちゃ色々ついているけど省略
-
Formデータ
Form item 値 説明 username hoge ユーザー名 password xxx パスワード
-
-page-6
- Keycloak は
username
とpassword
を検証して認証OKとなれば End-user へレスポンス 302 Found(リダイレクト) を返す
memo : ここに 認可コード が入っている
パラメータ | 値 | 説明 |
---|---|---|
Location | http://test-oidc-rp:8081/secure | リダイレクト先 (*1)で指定されたもの |
code | 050ab57b-64e1-410a-・・・ | 認可コード(Authorization Code) |
- End-user は リダイレクトのレスポンスを受けたので、そのままリダイレクト先に飛んでいく
-page-7
3. Get Access Token & ID Token
認可コードを取得してから Access Token(アクセストークン) と ID Token(IDトークン) を取得するまでのフロー
-
mod-auth-openidc
は Keycloak の トークンエンドポイント にPOSTする-
このとき Authorization ヘッダに Basic を設定する
ヘッダ 値 説明 Authorization Basic dGVz... Basic認証であることを示す
↑の値なんですが
Basic dGVzdDozM2I3MzJjNS0wMDZjLTQxNjMtOWM3Yy01NzVhNjBhMmEzNDg=
これは Basic認証であることを意味していて、Basic 以降のBase64をデコードすると
test:33b732c5-006c-4163-9c7c-575a60a2a348
となっています。
要はこの値で接続してくるクライアントを認証しています。→9. Client Authentication
クライアントIDとシークレットは auth_openidc.conf の
OIDCClientID
,OIDCClientSecret
です。 -
Form
Form item 値 説明 grant_type authorization_code 3.1.3.1. Token Request code 050ab57b-64e1-410a-・・・ 先程取得した 認可コード redirect_uri http://test-oidc-rp:8081/secure RPからOPに直接リクエストするバックチャネル通信なんでOPがリダイレクトのレスポンスしてくるわけではないと思うのですが Validation するため必須。
3.1.3.2. Token Request Validation
>redirect_uri
パラメータの値が, 最初の Authorization Request に含まれていたredirect_uri
パラメータの値と同一であることを確認
ということみたい。
-
-page-8
-
Keycloak は Authorizationヘッダの値とか認可コードを検証してOKであれば
mod-auth-openidc
にレスポンス を返す。
レスポンスはJSON形式で**Access Token(アクセストークン) と ID Token(IDトークン)**が含まれている。Key Value 説明 access_token JWT形式のデータ アクセストークン expires_in 60 アクセストークンの有効期限(60秒=1分) refresh_expires JWT形式のデータ リフレッシュトークン refresh_expires_in 1800 リフレッシュトークンの有効期限(1800秒=30分) token_type Bearer トークンタイプ id_token JWT形式のデータ IDトークン
-page-9
アクセストークンとは何か
リソースにアクセスするときの許可証。OAuthのそれと同じ。
IDトークンとは何か
ユーザーをちゃんと認証したよ、という証明書みたいなもの。ユーザー名とかの属性も入っている。
詳細は以下のサイトを見たほうがいい
-
続けざまに KeyCloak の jwks_url(証明書エンドポイント) から証明書をGETする。
-
証明書 = アクセストークン、IDトークンのJWTの署名を検証するために使う公開鍵
-
ここに入っている公開鍵でJWTを検証することでアクセストークン、IDトークンが改ざんされていないことを確認する
memo : jwks_url は OpenID Configuration に入っている
-page-10 -
-
UserInfo Endpoint(ユーザー情報エンドポイント) からユーザー情報をGETする。
-
ユーザー情報 = UsernameとかEmailとか
- ユーザー情報エンドポイントにアクセスする際のAuthorizationヘッダはBearerで、先程取得した アクセストークン を指定する
memo : UserInfo Endpoint は OpenID Configuration に入っている
-page-11
- ここまでで
mod-auth-openidc
は必要な情報を全て取得したことになる。End-userには一番最初にアクセスを要求されたURLに遷移するリダイレクトのレスポンスを返す。
パラメータ | 値 | 説明 |
---|---|---|
Location | http://test-oidc-rp:8081/secure/welcome.php | リダイレクト先 |
-page-12
4. Resource access
リダイレクト先に遷移する。リクエストを受けた mod-auth-openidc
はアクセスを許可しHTMLを返す。
note :
mod-auth-openidc
は Cookie mod_auth_openidc_session にアクセストークンを紐付けていてアクセストークンの有効性を確認しているようです。mod_auth_openidc_sessionを削除するとKeycloakに問い合わせて再度アクセストークンをもらってきているのでしょう。
-page-13
おつかれさまでした
よくわからないことがまだあるなぁ...
- ログアウトの動作 (Logout)
- ログインしたままTOPに戻って再度ログインしたときの動作(Return to top wthile logged in)
- アクセストークン/IDトークンの有効期限が切れたときの動作
蛇足(データサンプル)
OpenID Configuration
{
"issuer": "http://test-oidc-keycloak:8080/auth/realms/master",
"authorization_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/auth",
"token_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/token",
"introspection_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/userinfo",
"end_session_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/logout",
"jwks_uri": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/certs",
"check_session_iframe": "http://test-oidc-keycloak:8080/auth/realms/master/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"
],
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"registration_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/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"
],
"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",
"email",
"roles",
"profile",
"web-origins",
"offline_access",
"address",
"microprofile-jwt",
"phone"
],
"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": "http://test-oidc-keycloak:8080/auth/realms/master/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": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/auth/device",
"backchannel_token_delivery_modes_supported": [
"poll"
],
"backchannel_authentication_endpoint": "http://test-oidc-keycloak:8080/auth/realms/master/protocol/openid-connect/ext/ciba/auth"
}
Access Token
https://jwt.io/ でデコードできる
JWT
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJwSmdoalAxUVJLZ1lEWnFJVzNKV1dETnI3eUc5aEJiVGk4VV94SXh0Tmc4In0.eyJleHAiOjE2MjQ3NDc2MzIsImlhdCI6MTYyNDc0NzU3MiwiYXV0aF90aW1lIjoxNjI0NzQ3NTcxLCJqdGkiOiI2ZmU0NjkwNy1iZTFjLTQ2YWUtODlhYi03ZGIxMjI4YTJlMDYiLCJpc3MiOiJodHRwOi8vdGVzdC1vaWRjLWtleWNsb2FrOjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImFjMDg0OGU4LTUzZTMtNDQ4My1hNzM5LWQ3NjIzMTdhZjQ0NCIsInR5cCI6IkJlYXJlciIsImF6cCI6InRlc3QiLCJub25jZSI6IlVudkUtWjhwUS13MmxPSUVyd2F2WDF4dEo4eXlCNlhhV0l4cjRMQmxiZzAiLCJzZXNzaW9uX3N0YXRlIjoiZDk2OTQyNzctMDFhNy00OWRjLWJlMDktNTRhMzg3MDY2ZDkxIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLW1hc3RlciIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJob2dlIn0.ETQpOLqEPvTSBfwts85YwDMen8tw8ZUeF21w5LqdBaVquS7DuNcQpI-A_4RM3OR2L3XuwIfMYLk3AmGObZz_4bY7d1yfeBJYNwXXS1A6VJDQU3kZdGr9VZPAUoHcoMD6R4EZbG4nCl_idJ0b_bg4WEeY5IjdNLjcxrZZ4fax0TpuvBIoRJmnOIKMsKg5W7HyJYZ8nqKxFw1a3aGV2sy5tqeyAYordAO7_T4pgt-WpH73IJFqT7mNXorEnNEROqZQR7FAqU4Rs2mFBynAN1Sq_ICB8avYzF9QkLrUmud7A5oFvCjVi2WWHNxhhkM6x7Gv7gjqwlsaEofp9awkjqfFew
Decoded-Payload
{
"exp": 1625894396,
"iat": 1625894336,
"auth_time": 1625894336,
"jti": "193cba26-dcba-4704-9d39-31f88ee8339b",
"iss": "http://test-oidc-keycloak:8080/auth/realms/master",
"aud": "account",
"sub": "9e9e8079-e8c4-4eaa-baaf-bcd22707d9a7",
"typ": "Bearer",
"azp": "test",
"nonce": "B-3iE7nRNtsVs4D0r7YZw88-PPwBsQDoDKpOxrN3o9o",
"session_state": "ef353a37-809a-4945-b3f2-0d04d6d01e32",
"acr": "1",
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid profile email",
"email_verified": false,
"preferred_username": "hoge",
"email": "aa@aa.com"
}
ID Token
JWT
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJwSmdoalAxUVJLZ1lEWnFJVzNKV1dETnI3eUc5aEJiVGk4VV94SXh0Tmc4In0.eyJleHAiOjE2MjQ3NDc2MzIsImlhdCI6MTYyNDc0NzU3MiwiYXV0aF90aW1lIjoxNjI0NzQ3NTcxLCJqdGkiOiJjYjI3YmY1MC0zYmZjLTQxN2QtOWU1NS1jMzc4M2UyODFiMzEiLCJpc3MiOiJodHRwOi8vdGVzdC1vaWRjLWtleWNsb2FrOjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoidGVzdCIsInN1YiI6ImFjMDg0OGU4LTUzZTMtNDQ4My1hNzM5LWQ3NjIzMTdhZjQ0NCIsInR5cCI6IklEIiwiYXpwIjoidGVzdCIsIm5vbmNlIjoiVW52RS1aOHBRLXcybE9JRXJ3YXZYMXh0Sjh5eUI2WGFXSXhyNExCbGJnMCIsInNlc3Npb25fc3RhdGUiOiJkOTY5NDI3Ny0wMWE3LTQ5ZGMtYmUwOS01NGEzODcwNjZkOTEiLCJhdF9oYXNoIjoiUlZadkNhaEdCYWk2TlVydkVKam9mZyIsImFjciI6IjEiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImhvZ2UifQ.rMcNKLdfd64W0r9QIPIlXVIiyTi6MUhmAQX2H_Bp6eviEecRoPYHxawG5fXZS2iNKAzDL5OjHbGl_Yzxkjr2UPBB7UWfgVIcjfD3BiOQO-V4haa8O3gGPMx0Xm1LD6r5QVV6eARm5_FTvpO8xwmgVzW0KXRfn9M-HyofE4NEjsMQTAel8TY_U7H1KJsqTezEZRfHrtU7EwyO0OVRvfVXp58F9Ly5GtXNrMDlekQWdaTA222_Rk6Tm6h3KNgwUKwbigtBwMDK19ZXeJ94_sFcbHfKcbgnFhnzEYyZ-3rSM9SKtPh0JUlordUOU7FUQVqKxviOgwrj7Wqi-2kekBZnxg
Decoded JSON
{
"exp": 1624747632,
"iat": 1624747572,
"auth_time": 1624747571,
"jti": "cb27bf50-3bfc-417d-9e55-c3783e281b31",
"iss": "http://test-oidc-keycloak:8080/auth/realms/master",
"aud": "test",
"sub": "ac0848e8-53e3-4483-a739-d762317af444",
"typ": "ID",
"azp": "test",
"nonce": "UnvE-Z8pQ-w2lOIErwavX1xtJ8yyB6XaWIxr4LBlbg0",
"session_state": "d9694277-01a7-49dc-be09-54a387066d91",
"at_hash": "RVZvCahGBai6NUrvEJjofg",
"acr": "1",
"email_verified": false,
"preferred_username": "hoge"
}
jwks_uri Keys
{
"keys": [
{
"kid": "pJghjP1QRKgYDZqIW3JWWDNr7yG9hBbTi8U_xIxtNg8",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "zSlLHc3Znj4mpnGyyxr32XgT-cCP4YPUCGxQ4s7yuplhAeePO2vUUytlx0oekP1M8xVa4fFsmv1VNkbj8iF6k_gmyRJAoBjA6CEiV7p42-nQcwSV6i_V-iyXKejKoH7PKAQZmhUsz21fNEWhpprRL3s3iGQS5EQpdJf_ACIbSWAvU2GxczFUxTReVGBSjwWrtqdC1N-qvyVFoD_1o1HKD0wGGIxJS3Bt4qvYKuxrpXb_5iaK1lSYXj8r2nwd2tgs7qe1WgTFDpvh_ncLPIkNf08OLsH7CxoDs-sPQvbKgufsU1vTFhh0fXi6Z1pheO1mTnncs6KgLy_nlC7JskPM2Q",
"e": "AQAB",
"x5c": [
"MIICmzCCAYMCBgF6KFytNzANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjEwNjIwMDczODIwWhcNMzEwNjIwMDc0MDAwWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNKUsdzdmePiamcbLLGvfZeBP5wI/hg9QIbFDizvK6mWEB5487a9RTK2XHSh6Q/UzzFVrh8Wya/VU2RuPyIXqT+CbJEkCgGMDoISJXunjb6dBzBJXqL9X6LJcp6Mqgfs8oBBmaFSzPbV80RaGmmtEvezeIZBLkRCl0l/8AIhtJYC9TYbFzMVTFNF5UYFKPBau2p0LU36q/JUWgP/WjUcoPTAYYjElLcG3iq9gq7Guldv/mJorWVJhePyvafB3a2Czup7VaBMUOm+H+dws8iQ1/Tw4uwfsLGgOz6w9C9sqC5+xTW9MWGHR9eLpnWmF47WZOedyzoqAvL+eULsmyQ8zZAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIqK00VqPXHVl8gpybKsyyZCnz+w3HoFO+7c4pVtWHy7eREPdmY4pgyqWKyY4064J/ZJ7TK8JNs6tQf1/LZUmp6fRMXQVRJglJyGz/J4ZBg7kqmzxi9kroNRhcStMidYjEkUHhpTK3dIOfUZ4vaf/OfN3WE8JzsXG5Jxz7DY9wN3oUCeZf6/ju2Lb8gIKAq+7wmxhmkZEZNU21Rx9S6bz4mYMSFaEQ7ldg3y14doiCZYCeVSJSoq74uOdAv+kxdo/FsnGZT8GRKsvCwQMSYAe/l5ccHVceFK3Isxp2EZVNwD/6ytjMkUgUTibakJAGVJMouRZStiy2n2srQ2egDjKhA="
],
"x5t": "HaBzJVfpnNV6jtIK9ZtDn0F7mYA",
"x5t#S256": "VPN7LyGrZXA_gb6WBOkk-4pUWuzxxctuKAWtdm5mYzk"
}
]
}
Userinfo
{
"sub": "9e9e8079-e8c4-4eaa-baaf-bcd22707d9a7",
"email_verified": false,
"preferred_username": "hoge",
"email": "aa@aa.com"
}
Discussion