KeycloakでMattermost(Team Edition)にSSOログインする際に必要な数値IDをスクリプトマッパーでUUIDから生成する


概要

Keycloakの応答をGitLabに偽装してMattermost(Team Edition)に対応させる場合、GitLabのユーザーIDに対応するクレームをMattermostに渡す必要がある。詳細はネタ元の下記記事を参照のこと。

同記事で言及されている通り、GitLabのユーザーID(GitLabのDB上では users.id )はユニークな数値であり、Keycloakに標準で用意されているユーザープロパティ・属性には適当なものがない。

とはいえKeycloakのユーザーIDはUUID(v4)形式、つまり128bitの数値なので、16進数の FFFFFFFF-FFFF-4FFF-FFFF-FFFFFFFFFFFF のフォーマットから10進数に変換するスクリプトマッパーを用意すれば専用のユーザー属性を追加することなく対応できる。

スクリプトマッパーの作成

JavaScript

KeycloakのユーザーIDはDB上では user_entity.id に格納されており、スクリプトマッパーからは user.getId() で取得できる。

今回は先頭の12桁を使用し、48bitの整数を得る。

uuid-to-int48-mapper.js
parseInt(user.getId().split("-").join("").substr(0,12),16).toString();

toString() を行うのはKeycloakの仕様によるもの。出力時のフォーマットはクライアント設定で選べる(後述)。

jar

スクリプトマッパーをKeycloakの管理コンソール上で直接記述する機能もあるが大分前からdepricatedのため、jarファイルに固めて読み込ませる。

公式ドキュメントに従って keycloak-scripts.json にメタデータを記述する。例えば以下のようになる。

keycloak-scripts.json
{
  "mappers": [
    {
      "name": "UUID to INT48",
      "fileName": "uuid-to-int48-mapper.js",
      "description": "Convert Keycloak User ID (UUID v4) to 48-bit integer (16 digits) for Mattermost"
    }
  ]
}

ファイルを規定の構造でzip圧縮し、拡張子を jar に変更する。

uuid-to-int48-mapper.jar
|-- META-INF
|   `-- keycloak-scripts.json
`-- uuid-to-int48-mapper.js

書庫のルートにMETA-INFディレクトリとJSファイルが配置されるようにする。

Keycloakの設定

jarの配置

作成したjarファイルを standalone/deployments に配置する。
Keycloak公式Dockerイメージの場合は /opt/jboss/keycloak/standalone/deployments にマウントする。

JavaScriptプロバイダーの有効化

設定ファイル profile.properties でJavaScriptプロバイダー(スクリプトマッパーはこの機能の一部)を有効化する。

profile.properties
feature.scripts=enabled

設定ファイルは standalone/configuration/profile.properties に配置する。
Keycloak公式Dockerイメージの場合は /opt/jboss/keycloak/standalone/configuration/profile.properties としてマウントする。

上記手順を実施してKeycloakを起動すると、正常に読み込まれていれば「管理コンソール→サーバー情報→プロバイダー」に表示される。

クライアント設定

Mattermostのクライアント設定で作成したスクリプトマッパーをトークンクレーム名 id に割り当てる。型は long とする。

動作確認

最初の12桁 82286c9c2d4c を10進数に変換すると 143110132477260

Mattermostの users.authdata に同じ値が入っている。