はじめに
何か書こうとしたら何も書けなかったので、方向転換しました。
タグのポエム初心者って、ポエムの初心者なのか、初心者のポエムなのか、どっちなのか分からなくなってしまいました。そんな夜。
登場人物
OpenID Connect
https://www.openid.or.jp/document/
Keycloak
https://www.keycloak.org/
https://openstandia.jp/
アクセストークン
IDトークン(裏で働いている)
HTTPステータスコード401
HTTPステータスコード403
雑なネタばれ
アクセストークンと呼ばれるJSON形式のデータを見せてKeycloakの機能を引き出す。トークンを持ってればアカパス認証なんかしなくても許される
OpenID ConnectのアクセストークンをKeycloakからもらう
Keycloakにはトークンを配ってくれるエンドポイントがあるので、門をたたいてみましょう。トークンをくれるから、「トークンエンドポイント」と呼ばれています。
さて、例としてユーザ「admin」さんのトークンをもらってきました。
先ほどから「アクセストークン」と言っていたのは、以下の「access_token」に該当します。「access_token」の値は一見するとランダムな文字列ですが、ルールに沿って暗号化しているため、元に戻すことができます。
試しにhttps://jwt.io/ へ行って、下のアクセストークンを張り付けてみてください。中に名前が含まれているのが分かると思います。
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJpTUJ1U09BTjZNZTZQWF9Nb0JvOVFvZi1lMzZCd3QzamFkMzhVamFpdjNJIn0.eyJleHAiOjE3MzMzMTg1NzUsImlhdCI6MTczMzMxODUxNSwianRpIjoiZjQwMzA0NjQtNzNjYy00M2ZhLWI3ZjktY2UyNWYwM2M3OWI3IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoxODA4MC9yZWFsbXMvbWFzdGVyIiwic3ViIjoiZDI3ZmI5MDctZGEzMS00Zjk0LWI1NjYtZjU5ZmZhOGE5YTUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwic2Vzc2lvbl9zdGF0ZSI6ImIxYTM0NjBhLTAxMzktNGYzOS05YzkyLWZkMzY5YzlhNDRjMyIsImFjciI6IjEiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJzaWQiOiJiMWEzNDYwYS0wMTM5LTRmMzktOWM5Mi1mZDM2OWM5YTQ0YzMiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiLjgb_jgabjgY_jgozjgaYg44GC44KK44GM44Go44GG44GU44GW44GE44G-44GZ77yBIiwicHJlZmVycmVkX3VzZXJuYW1lIjoi44Gr44Gb44KC44GuIiwiZ2l2ZW5fbmFtZSI6IuOBv-OBpuOBj-OCjOOBpiIsImZhbWlseV9uYW1lIjoi44GC44KK44GM44Go44GG44GU44GW44GE44G-44GZ77yBIn0.aHcqGmSunjdWJX2JN7EG80ANTPZLKnh8b0bzzA4AceIpDdMZnGO2ACq82kjt9FbFU4uH4zkNIjMRVBvZGxT73HrRsyq3Yh6JCmFU1ofo8MbxNEV-R-pNFQ16hVpTggJYT3HsNig6AvL_5sBe054PlIh0CCpznnBXOtDilBnvnmQOXM35_g1Rmuc4jALd683_8JuChRk074QUzqtMxgmeUYLoxdHPrAzS5zCOsfK_XstcBAkgQ0S5ckRGsVcV4AzxVc0E3W6YLJ5dIDOK3fFAqHkl1knbCVvdlFGmMl_Gtek-xeWi28sKjMw-5KVBDUPu-9rsWnhElYp6_JQU_qHonQ",
"expires_in": 60,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0ZmY0MjRkOS02YjE0LTQ4ODItOWM3Mi03ZTVmODcyMmM0ZjEifQ.eyJleHAiOjE3MzMzMjAzMTUsImlhdCI6MTczMzMxODUxNSwianRpIjoiOTE5ODA1YTUtMTFhMC00N2Y0LWFjMDctZDAxNDk0MmQ3NDAxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoxODA4MC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxODA4MC9yZWFsbXMvbWFzdGVyIiwic3ViIjoiZDI3ZmI5MDctZGEzMS00Zjk0LWI1NjYtZjU5ZmZhOGE5YTUyIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiJiMWEzNDYwYS0wMTM5LTRmMzktOWM5Mi1mZDM2OWM5YTQ0YzMiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJzaWQiOiJiMWEzNDYwYS0wMTM5LTRmMzktOWM5Mi1mZDM2OWM5YTQ0YzMifQ.bn6wBHNRxloQhiHqHsC9kmk0CTDYC9fsev3ZVIMw3cM",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "b1a3460a-0139-4f39-9c92-fd369c9a44c3",
"scope": "profile email"
}
KeycloakのAdminAPI
KeycloakにはAdminAPIと呼ばれる最強の能力があり、URI一つでKeycloakのあらゆる力を引き出すことができます。さっそく、そのうちの一つである「ユーザ一覧取得API」を呼んでみましょう。
怒られました。「401 Unauthorized」の表示の通り、Admin APIを使うには、認証が必要です。でも毎回アカパス認証なんてしたくないので、アクセストークンを振りかざします。
リクエストヘッダにアクセストークンを載せてあげると、ちゃんと機能してくれました。
ちなみに、中身は以下のようになりました。ユーザ情報が思いっきり来てます!こんな機能、誰でも使えたら危険ですね。
[
{
"id": "09ec4ad2-d573-4eb1-862e-7b719c5cc9dd",
"createdTimestamp": 1733240170292,
"username": "admin",
"enabled": true,
"totp": false,
"emailVerified": false,
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
}
},
...略
]
ところで、アクセストークンさえあればユーザ情報が手に入る!そこで、ユーザ「nonadmin」さんに、自身のアクセストークンを付与してエンドポイントを叩いてもらいましょう。
なんと、またエラー!でも、先ほどの401と異なり、今度はHTTP 403エラーでした。「Forbidden」とあるように、nonadminさんには権限が無かったのですね。
このように、ユーザ毎に権限を設定することができます。アクセストークンがあっても、権限のないユーザではAdmin APIを扱うことはできません。
最後にひとつ、便利なAdmin APIをご紹介しましょう。ユーザ(アカウント)削除のAPIです!その気になればユーザ(アカウント)もURIひとつで消せます。こんな恐ろしいことは無い
例えば、ユーザ「将来の不安」を消したいなら、
IDを指定するだけで簡単に消すことができます。
おわりに
Keycloakを使って、OpenID Connectのアクセストークンを手軽に扱えるところをご紹介したかったです。Keycloakの一側面だけ、OpenID Connectについては全く現れないという状態でしたが、知るキッカケになれば幸いです。