KeycloakをIdpに使ってSAML認証(3)

この記事は、KeycloakをIdpに使ってSAML認証(1)およびKeycloakをIdpに使ってSAML認証(2)に続く記事である。(1)はKeyCloakのインストール、(2)はKeyCloakをSAMLのIdPとして、INTER-Mediatorで作ったアプリケーションに認証処理を提供する方法を記述したが、認証が通ったことはわかるものの、SAML属性にユーザ名が入っていないということで、INTER-Mediator側では想定した状態になっていなかった。そして、その点は解決したので、ここに記載しておく。

KeyCloak をIdPとし、SimpleSAMLphpをSPに設定している場合で、SP側の管理ページに入り、そこで認証をしてみる。そこでは、アプリケーション側で得られてるSAMLの属性がわかるので、その部分の確認と、ユーザ名を入れる拡張を進めてみた。まず、単にKeyCloakのClientとしてSAML SPを登録した状態では次のようになる。管理ぺ時のTestのところにSPが見えている(ここでは「default-sp」)。そのSPをクリックする。

すると、KeyCloakの黒い背景の認証ページに移動する。ここで、既存のkcuser1で認証をした場合、次のように、得られる属性が見えている。(2)で説明した通り、ここでも同様にRoleという属性しか見えていない。

しかしながら、以下のようにKeyCloak側を設定すると、次の図のように、kcuser1でログインした結果、そのユーザの姓名とメールアドレスに加えて、ユーザ名も取得することができた。

INTER-Mediator側で、取得した属性をチェックすると、このような感じになる。以前は、Roleだけだったのが、ユーザ名や氏名、メールアドレスも、ともかく取得できている。

ここで、INTER-Mediatorのparams.phpファイルでは、このように取得される属性から必要なデータを得られるように、$samlAttrRules変数の配列を定義しておく必要がある。この配列のキーは、ユーザテーブル(authuser)のフィールド名である。配列のキーに対する値は、SAMLの属性から取り出す時のキーと、|で挟んで配列の要素番号を指定している。メールや氏名については、前述の属性のダンプにあるように、複雑な記号がキーになっているので、それをコピペするなどして、きちんと配列を定義しなければならない。

いずれにしても、これで、INTER-Mediatorのアプリケーションで、KeyCloakをIdPとして認証ができることが確認できた。

どうすれば属性を増やすことができるのか

ということで、タイトル通りの疑問がここで沸く。言い換えれば、KeyCloakに設定したユーザでの認証については、「何かしなければRoleしか得られない」ということだ。

まず、左側で、Client Scopesを見てみよう。ここをみると、SAMLプロトコルに対しては、role_listという名前のものしか定義されておらず、他はみんなOpenIDのものである。以下の画像には1ページ目しか見えていないが、もう1項目だけ次のページにあり、それはOpenID向けのものである。ここを見て、「属性にRoleしかない」という状況と、Client scopesにSAMLのものはrole_listしかないという結果に大きな関連性があると着目して、ここに設定を加えれば良いということがわかる。

このリストで、Create client scopeボタンをクリックする。そうすると、以下のような画面になる。ここで、Nameを指定するが、この名前は、このリスト上の名前であり、すでに存在する名前はつけられない。ここでは、snとした。そして、もう1つProtocolからSAMを選択しておく。とりあえず、この2つで良いようだ。Protocolは後から変更できないので忘れないようにする。そしてSaveボタンをクリックする。

Saveボタンをクリックすると、Clinet scopeの1項目を編集する画面に入るのだが、上部のタブのMappersをクリックする。最初は次の図のように、No mappersとなっている。ある属性を得るには、マッパーを利用して、既存のどこかの値を持ってくるという設定を記述しないといけないようである。

ここでまず、Add predefined mapperボタンをクリックして、つまりは既定義のマッパーを探して設定する。ちなみに、既定義のマッパーが一覧されるので、該当する項目にチェックを入れて、Addボタンをクリックする。ただ、これをよくみると、既定義のマッパーでは、sureName、givenName、emailの3つしかない。ここでは、snに対するものとして、X500 surenameにチェックを入れて、Addをセットする。ちなみに、すでに設定したものはこのリストでは表示されなくなる。

この設定を、sn、gn、mailというClient scopeに対して行った。

では、usernameはどうすればいいか?まずは、usernameに対応するためのClient scopeの1項目を作る。もちろん、ProtocolをSAMLにするのを忘れないようにする。そしてマッパーを登録すが、usernameのマッパーは既定義には存在しないのでConfigure a new mapperをクリックする。すると、次のような選択画面が表示される。何を選択するか迷うが、とりあえず、User Attribute、User Propertyのいずれも成功している。ここではUser Attributeを選択したとする。

すると、次のようなマッパーを定義する画面に入るので、ここで、Name以下4つの項目で全部、usernameと入力する。なお、ここでは最後の項目にあるように、SAML属性上でのキー名も入力できるので、属性上の値の解釈も分かりやすくなる。入力後、Saveボタンをクリックして保存しておく。

こうして、4つのClient scopeを追加した。Client scopeの一覧で、SAML Protocolに絞って一覧を示すとこのような感じである。username以外は、既定義のマッパーを使っている。

これでOKかと思ったのだが、まだRoleしか属性に入っていない。さらに続いて、次のように設定を行う。Clientsを選択すると、クライアントのリストが表示される。ここで、追加したSAML SPの項目のリンクをクリックする。

そして、Clientの設定画面が出てくるので、上部のタブで、Client scopesを選択する。規定値では、role_listが見えているはずだが、いずれにしても、Client scopesに登録し、さらにここで追加する必要があるということで、ここで、さらに選択を加えないといけない。

Add client scopeボタンをクリックすると、次のように、Client scopesで定義したProtocolがSAMLの項目が一覧される。とりあえず、ここでは全ての項目にチェックを入れて、Addボタンをクリックする。さらに選択するポップアップが出てくるので、Defaultを選択しておく。

SAML SPのClient scopesの設定が次のようになったらOKである。

ここまで設定を行うことで、最初に示したように、SAML属性にusernameや氏名、メールアドレスを含めることができ、INTER-Mediatorでの利用が可能になった。