Closed5
keycloakについてまとめる : 認証認可
Keycloakとは
- ユーザやサーバリソースの認証/認可/管理の機能を提供するOSSソフトウェア。
- 2023/4にCloud Native Computing Foundation(CNCF)のプロジェクトに追加され、OSSの定番になることが期待されている。
提供機能
-
ユーザー認証
ユーザーが本人であることを確認する。 -
ユーザー認可
ユーザが特定のリソースにアクセスできる権限を与える。 -
シングルサインオン(SSO)
一度のログインで複数の関連サービスにアクセスを許可する。 -
ユーザーフェデレーション
異なるデータソースからのユーザー情報を統合します。 -
ソーシャルログイン
外部サービス(Google/FaceBookなど)を使用したログインをサポートします。
用語解説
-
Identity
特定のユーザーやリソースを識別する一意な情報(ユーザの身元情報)。 -
ユーザーフェデレーション
複数の外部データベースのユーザー情報をKeycloakにおいて統合し一元的なユーザー管理を可能にする。 -
SSO
ユーザーが一度の認証で複数の関連サービスに認証済みとしてアクセスできるようにする仕組み。 -
Idp(Identity Provider )
ユーザーのIdentityを管理し、認証サービスを提供するシステム。 -
sp(Service Provider)
ユーザーがIdp経由でアクセスしようとしているサービスやアプリケーション。 -
AD連携
Windowsで提供しているユーザーアカウントや端末情報を管理する機能(Active Directory)とユーザ情報を連携すること。
Keycloakの認可方式
OAuth(OAuth2.0)
- 認可のための手順を定めたプロトコル。
- 認可の過程でアクセストークンを発行する。
アクセストークンとは
- 特定のユーザがどのリソースにアクセスする権限をもっているかの情報を含むトークン。
- JSON Web Tokenと呼ばれる、JSONデータを暗号化した形式で発行される。
- アクセストークンには有効期限が存在し、認可サーバ(keycloak)上で設定できる。
アクセストークン発行プロセス
- ユーザがクライアントアプリにアクセスする
- クライアントアプリはユーザをKeycloakにリダイレクトさせる
- ユーザはKeycloak上でユーザID/PWを使ってログインをする。
- アクセストークンが発行され、クライアントアプリに渡させる。
- アクセストークンを使ってクライアントアプリはリソースサーバ(API/DB)にアクセスする。
- ユーザがアクセス権限を持たないリソースにはアクセストークンを使ってもアクセスできない。
アクセストークン検証プロセス
アクセストークンの検証は、リソースサーバ(APIやDB)が有効であることを確認するプロセスです。
-
署名の検証
アクセストークンはJSON Web Token(JWT)形式で、デジタル署名が付いています。
リソースサーバ(APIやDB)は公開鍵を使用してこの署名を検証し、トークンが信頼できる認証サーバ(Keycloak)によって発行されたものであることを確認します。 -
クレームの検証
トークンには「クレーム」と呼ばれる一連の情報が含まれています。
リソースサーバ(APIやDB)は、トークンの有効期限(exp)、発行者(iss)、対象者(aud)などのクレームを検証して、トークンが有効であることを確認します。
OAuthの注意点
- OAuthで発行されるアクセストークンにはログインしたユーザの情報が限定的にしか含まれておらず、 誰に対して発行されたアクセストークンか確認できない。
具体的な問題になるケース : OAuthを認証で使った場合
(前提)
- サイトAにKeycloakでログインするとアクセストークンが発行される。
- サイトAはアクセストークンがサイトAのどのユーザと結びついてるのかわからない。(誰かがログインに成功したことはわかるが、誰がログインしたかわからない。)
- そのため、アクセストークンを使ってユーザ情報をサーバから取得する必要がある。
(本題)
- 悪意ユーザがサービスAにアクセス
- サービスAがKeycloakに悪意ユーザをリダイレクト
- 悪意ユーザがKeycloak上で自身のアカウントでログイン
- KeycloakがサービスAにアクセストークンを渡す。
- このタイミングで悪意ユーザが発行されたアクセストークンを、管理者ユーザのアクセストークンに置き換える。
- サービスAは管理者ユーザのアクセストークンに管理者ユーザのログイン情報をサーバから取得する。
- 悪意ユーザは管理者ユーザとしてログインされる。
Keycloakの認証方式
認証方式 : OIDC(OpenID Connect)
- OAuth 2.0をベースにした認証プロトコル。
- アクセストークンとIDトークンを発行する。
- IDトークンにはユーザの識別情報が含まれている。
IDトークンとは
- ログインしたユーザの識別情報を含む。
- 誰が : ログインユーザ
- いつ : ログイン日
- どこで : Keycloakの識別情報
- 誰に : Keycloakを介してログインしたいクライアントアプリ
- どれぐらいのリソースに対して : アクセス対象となるユーザーの権限範囲
- JSON Web Tokenと呼ばれる、JSONデータを暗号化した形式で発行される。
- IDトークンにどのような情報を持たせるかはID プロバイダー(keycloak)で設定できる。
IDトークン発行プロセス
- アクセストークン発行プロセスとほぼ一緒
- Keycloakではアクセストークンを発行する際に、IDトークンも一緒に返ってくる。
IDトークンを使った認証プロセスによる不正アクセス防止
(前提)
- ユーザがサイトAにKeycloakでログインするとアクセストークンとIDトークンが発行される。
- サイトAはアクセストークンがサイトAのどのユーザと結びついてるのかをIDトークンをもって確認する。
(本題)
- 悪意ユーザがサービスAにアクセス
- サービスAがKeycloakに悪意ユーザをリダイレクト
- 悪意ユーザがKeycloak上で自身のアカウントでログイン
- KeycloakがサービスAにアクセストークンとIDトークンを渡す。
- このタイミングで悪意ユーザが発行されたアクセストークンを、管理者ユーザのアクセストークンに置き換える。
- サービスAはIDトークンをもってユーザを確認するので、悪意ユーザは悪意ユーザのユーザ情報でログインされる。
- またIDトークンにはいつどこで発行されたのかがのっているので、IDトークンを置き換えたとしてもサービスAハそれを検知できる。
IDトークンとSSO
- ユーザがサイトAにKeycloakでログイン済みだとする
- ユーザがサイトBにアクセスし、Keycloakにリダイレクトされる
- Keycloakはブラウザのセッションをみて、ユーザがKeycloakにログイン済みだということを確認する
- ユーザはログインすることなく、サイトBに返される
- サイトBにはKeycloakからアクセストークンとIDトークンが渡される。
- IDトークンによってログインユーザを確認する。
実践してみる
- KeycloakとKeycloakを介してログインしたいクライアントアプリをローカルに立てる。
- Keycloakは公式のDockerイメージを使う
- ログイン用のアプリは Next.js + NextAuth.js を使う。
1. Keycloakでクライアントアプリ用の情報を登録する。
- Realm : develop
- Client : test-client
- Valid Redirect Url : http://localhost:3000
2. クライアントアプリ(nextauth-example)の設定
NEXTAUTH_URL : http://localhost:3000
KEYCLOAK_ID : test-client
KEYCLOAK_SECRET : Client設定のCredentialsのClient Secret
KEYCLOAK_ISSUER : http://localhost:8080/realms/develop
3. ログインしてみる。
4. アクセストークン/IDトークンの中身
- なんかアクセストークンにもユーザ判別情報が含まれている?
- → クライアントスコープでどの情報をトークンに含めるか設定できるらしい
- → そもそもアクセストークンはクライアントアプリ側で検査されるべきではないらしい(後述)
アクセス トークン側では、リソースへのアクセス (API の呼び出しなど) が許可されていることを示すために考えられました。
クライアント アプリケーションは、この理由のためにのみこれを使用する必要があります。言い換えれば、アクセス トークンはクライアント アプリケーションによって検査されるべきではありません。これはリソース サーバーを対象としており、クライアント アプリケーションはアクセス トークンを不透明な文字列、つまり特定の意味を持たない文字列として扱う必要があります。アクセス トークンの形式を知っている場合でも、クライアント アプリケーションでその内容を解釈しようとしないでください。前述したように、アクセス トークンの形式は認可サーバーとリソース サーバーの間の合意であり、クライアント アプリケーションが侵入すべきではありません。ある日、アクセス トークンの形式が変更された場合に何が起こるかを考えてみましょう。クライアント コードがそのアクセス トークンを検査していた場合、予期せず壊れてしまいます。
アクセストークン
IDトークン
リフレッシュトークン
- アクセストークンの有効期限が切れた後でも、ユーザーを再認証することなく新しいアクセストークンを取得できるようにするためのトークン
- OIDC認証時にIDトークン/アクセストークンとともに返される
なぜ必要か
- アクセストークンの有効期限を長くすれば、必要ないのではないか
- → アクセストークンはり万が一トークンが漏洩した場合に備えて、有効期限は短く設定するべき
- → リフレッシュトークンの有効期限は少し長めに設定する。
オフライントークン
- ユーザーがオフラインの状態でもアプリケーションがユーザーの代わりにリソースサーバーにアクセスできるようにするための特別な種類のリフレッシトークン
- 主に、ユーザーが直接アクティブに操作していないときや、アプリケーションがバックグラウンドで動作しているときにリソースへのアクセスを継続的に保証するために使用される。
- オフライントークンは不正アクセスやトークンの漏洩があると、攻撃者が長期間にわたってユーザーのリソースにアクセスできる可能性がある。そのため、アクセスできるリソースのスコープは制限しておく必要がある。
このスクラップは2024/03/11にクローズされました