keycloakでOIDC認証するときに知っておくと良いこと

- (17 min read)

Contents

keycloakを使ってOIDC認証を導入することになり、設定画面で何を設定すべきかなどに困ったのでまとめておく。
前提

  • OAuth2の基本的な理解
  • OIDCの基本的な理解()
    • OIDC自体を知りたい場合はこの説明とかがわかりやすいと思う
  • keycloakのOIDCクライアントは作成済み(手順)

極めて単純なkeycloakの要素

keycloakの設定方法が分かりづらいのは管理画面に設定する項目が大量にあるからだが、極めて単純化すると最初に知るべきなのはrealm, client, userくらいである。

realm

用語集の記述を抜粋すると

レルムは、ユーザー、クレデンシャル、ロール、および、グループのセットを管理します。ユーザーは属しているレルムにログインします。レルムは互いに分離されており、制御するユーザーのみを管理して、認証することができます。

となっている。言ってみればnamespace的なもので、複数アプリケーションでシングルサインオン(SSO)するときは同一のrealmにユーザーやアプリケーションを登録する

client

用語集の記述を抜粋すると

クライアントは、Keycloakにユーザーの認証を要求できるエンティティーです。多くの場合、クライアントはKeycloakを使用して自分自身を保護し、シングル・サインオン・ソリューションを提供するアプリケーションとサービスのことを指します。

となっている。keyclaokを利用するアプリケーションのことで、複数アプリケーション間でSSOを実現するときはアプリケーション分clientをrealmに登録する。

uesr

用語集の記述を抜粋すると

システムにログイン可能なエンティティーのことです。電子メール、ユーザー名、住所、電話番号、生年月日など自分自身に関連する属性を持ちます。また、グループ・メンバーシップが割り当てられたり、特定のロールが割り当てられたりします。

となっている。認証されるユーザーのこと。

関連図

単純に考えると、keycloakの役割は以下である。

  • アプリケーション(client)に変わってuserの認証を行う
  • clientや認証したuserの情報をOIDC tokenに変換してアプリケーションに提供する

あるrealmでの要素間の関係は以下のようになる。OIDC tokenの生成元となる要素と、生成されるOIDC要素を色で分けている(OIDCはkeycloakで使えるプロトコルのひとつなので<<protocol>>としている。OIDC以外のプロトコル(SAMLやOAuth2)を利用するときはtokenが変わるだろう)
keycloakの要素に記載した > Clients というのは実際にkeycloakの設定画面からアクセスしたときのパンくずを表している。

simple_keycloak

単純でないkeycloakの要素

上の項で説明したようにkeycloakはrealm,client,userの設定をOIDCのtokenに変換するわけだが、clientuserのどの情報をOIDC tokenに反映するかの設定をしたり、OIDCの仕様にない情報をtokenに埋め込めるようになっている。これらの設定がkeycloakの管理画面を難しくしている要因だろう。
なお、OIDCを通して得られる情報としてID token,やAccess token,認証されたユーザーに関する情報を取得するためのUserInfoエンドポイントがある。ただし、Access tokenはOAuth2のもので、実装方法も認可サーバーに依存している。

role

用語集の記述を抜粋すると

ロールは、ユーザーのタイプまたはカテゴリーを識別します。 Admin、user、 manager、employee はすべて、組織内に存在する典型的なロールです。アプリケーションは、ユーザーの扱いをきめ細く管理することが難しくなる場合があるため、個々のユーザーではなく、特定のロールにパーミッションを割り当てることが多いです。

まずはroleについて。これはあまり難しくないがuserに属性を付けるのに使う。OIDCがデフォルトで持つユーザー情報にはroleは存在しないので、組織情報などを付与できると便利。注意が必要なのはroleはkeycloak内部で権限情報として利用されることもあるということ。(特にdefaultで用意されているrole)にはそれらの権限が付与されており、keycloakのRest apiを使うときなどにroleの有無によって実行できる操作が変わってくる。
また、realm単位とclient単位のroleが存在する。

realm role

realm全体で使えるrole(ドキュメント)

client role

client単位で使えるrole(ドキュメント)
設定箇所がclientからなことに注意

user

前述の通りだが、userroleを結びつけるための設定が必要

user role mapping

用語集の記述を抜粋すると

ユーザー・ロール・マッピングは、ロールとユーザーの間のマッピングを定義します。ユーザーには、0以上のロールを関連付けることができます。このロールマッピング情報を、トークンとアサーションにカプセル化して、アプリケーション(client)が管理するさまざまなリソースに対するアクセス許可を決定できるようにします。

userroleを結びつける設定。注意が必要なのが、デフォルトだとuserに結びつけたrole情報はすべてtoken内に表示されることである。roleの説明で記載したが、roleはkeycloak内部で権限情報として利用されることもあるので不正にtokenを取得されたときに悪用される可能性がある。それを防ぐための仕組みがclientに対して設定できるrole scope mappingである

client

前述の通りだが、keycloak内のどの情報をtokenに含めるかの設定を行うmappingの設定をrole scope mappingprotocol mapperで行っている。

role scope mapping

userに対して設定したroletokenに含めるかどうかの設定ができる(ドキュメント)

protocol mapper

用語集の記述を抜粋すると

各クライアントに対して、どのクレームおよびアサーションをOIDCトークンまたはSAMLアサーションに格納するかを調整できます。クライアントごとに、プロトコル・マッパーを構成します。

クレームとはOIDCのtokenを構成する要素(tokenはクレームの集合)
role scope mappingrole情報をtokenに含めるかどうかを設定しているが、それ以外のtokenに乗るべきすべての情報はprotocol mapperで設定されている。keycloak内部でprotocolといったときはOIDC,OAtuh2,SAMLといった認証/認可プロトコルのことを意味していると思ってよい。

client scope

前述の通りtokenにどのような項目を乗せるかはclientが設定しているが、clientが複数ある場合何度も同じ設定を繰り返すのは面倒(OIDCのtokenなどは仕様でも決まっているのでわざわざ自分で設定したくない)
そのため複数clientで使い回せるmappingの設定をする仕組みがclient scopeである。 用語集の記述を抜粋すると

クライアントが登録されたら、そのクライアントのプロトコル・マッパーとロールスコープのマッピングを定義する必要があります。いくつかの共通の設定を共有することで、新しいクライアントの作成を容易にするために、クライアント・スコープを保存すると便利なことがよくあります。これは、 scope パラメーターの値に基づいて条件付きでクレームやロールを要求する場合にも便利です。Keycloakは、このためにクライアント・スコープの概念を提供します。

設定画面ではトップレベルに用意されているClient ScopesClients配下に用意されているClient Scopesがあるので注意。前者がclient scopeの定義で後者がclientclient scopeを結びつけるためのもの

service account

最後にservice accountについて説明しておく。keycloakで単に認証だけ行い、rest apiなどを設定しない場合はこの設定は不要なので読み飛ばして構わない。

用語集の記述を抜粋すると

各クライアントには、アクセストークンを取得するための組み込みサービス・アカウントがあります。

となっているが、これだけ読んでもよくわからないと思う。 まずkeycloakのREST APIを利用するには事前にトークンを取得する必要がある。このトークンはaccess tokenとよばれOAuth2のそれと同一である。このaccess tokenを取得する方法は2つある(参照)

  1. master realmのユーザー名とパスワード名でaccess token取得のためのAPIを叩く
  2. service account を利用してaccess token取得のためのAPIを叩く

1のmaster realmのユーザーとパスワードを利用する方法は単純ではあるが、master realmにREST API用のuserアカウントを作る(もしくは既に存在する強い権限をもつuserアカウントを使う)必要があるためユーザー名、パスワードの管理を含めて煩雑である。
2のservice accountを利用すると1の不便を解消できる。service accountはOIDCのCode Grant Flowを利用するclientにだけ生成される内部的なuserである。対象のclientのcredentialコードを利用するだけでtoken取得のためのAPIを叩くことができる。そのためmaster realmに設定を追加する必要がない。また、service accountを利用したときに得られるaccess tokenの権限はclientService Account Roleという箇所から設定できる。ここら辺keycloak自身もOIDCやOAuth2の仕組みを上手く利用しているのだなと感じる。

関連図

上述した要素たちを関連図に付け加えると以下のようになる

keycloak 元々書いてあったclient,user以外にtokenの元情報になるroleとそれらから派生した要素(realm role, client role, service account)は色をまとめてある。それ以外はkeycloak内部の情報をtokenに反映するときのマッピングや制限であることがわかるだろう。引き続き各要素には管理画面のどこから設定できるかを記載してある。

keycloakの難しさは

  • 設定項目の名前から具体的に何が設定されるかがわかりにくいところ
  • 設定箇所の多さと、それ故に管理画面内のどこで何が設定されるのかがわかりにくいこと

だが、それぞれ

  • 設定項目の名前から具体的に何が設定されるかがわかりにくいところ
    • 本記事の説明を参照しつつkeycloak独自の要素とprotocol側の要素の名称をきちんと区別し、用語の意味を理解する
  • 設定箇所の多さと、それ故に管理画面内のどこで何が設定されるのかがわかりにくいこと
    • 関連図を参考に設定する箇所を探す

ことで少しでもkeycloak導入の手助けになれば嬉しい