概要
Keycloakで開発用オンプレブラウザアプリ類をSSO化するにあたり、Keycloak上のユーザープロパティ/ユーザー属性が各アプリのユーザー情報にどのようにマッピングされているか、またどの程度調整が可能かを(軽めに)調査した。
調査対象とちょっとした結論は以下の通り。
App |
Version |
認証方式 |
表示名指定 |
同期 |
GitLab |
13.9.3 |
SAML |
可 |
|
Gitea |
1.13.4 |
OIDC |
不可 |
|
CodiMD |
2.3.2 |
SAML |
可 |
あり |
Wiki.js |
2.5 |
SAML |
可 |
|
GROWI |
4.2.12 |
SAML |
制限あり |
|
Mattermost |
5.32.1 |
GitLab OAuth2 |
可 |
あり |
rocket.chat |
3.12.1 |
SAML |
可 |
|
Wekan |
5.05.0 |
OIDC |
可 |
|
TAIGA |
6.0.7 |
GitLab OAuth2 |
制限あり |
|
PENPOT |
1.3.0-alpha-1 |
GitLab OAuth2 |
可 |
|
NextCloud |
12.0.0.13 |
SAML |
可 |
あり |
※空欄は未調査
Keycloak
バージョン: 12.0.4 (Docker)
ユーザープロパティ

ユーザー属性

※ longId
はMattermostで使用する(後述)
GitLab
KeyCloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
email |
email |
Prop |
username |
username |
Prop |
firstName |
first_name |
Prop |
lastName |
last_name |
Attr |
nickname |
name |
GitLab側のマッピング
docker-compose.yml
︙
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=email
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=name
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=username
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=first_name
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=last_name
︙
結果

DB Field |
SAML Attr |
変更 |
備考 |
username |
username |
不可 |
|
name |
name |
可 |
表示名 |
email |
email |
可 |
|
- ログインIDやmention等に使われるusernameと表示名であるnameが分離しており、それぞれマッピングで個別に紐付けられる
- usernameはKeycloakでも変更できないため必ず等しくなる
- first_nameとlast_nameは使われない模様
Gitea
- バージョン: 1.13.4 (Docker)
- 認証方式: OpenID Connect
KeyCloak側のマッピング
なし
Gitea側のマッピング
なし
claimの初期化コード
openidConnect.go
const (
// Standard Claims http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
// fixed, cannot be changed
subjectClaim = "sub"
expiryClaim = "exp"
audienceClaim = "aud"
issuerClaim = "iss"
PreferredUsernameClaim = "preferred_username"
EmailClaim = "email"
NameClaim = "name"
NicknameClaim = "nickname"
PictureClaim = "picture"
GivenNameClaim = "given_name"
FamilyNameClaim = "family_name"
AddressClaim = "address"
// Unused but available to set in Provider claims
MiddleNameClaim = "middle_name"
ProfileClaim = "profile"
WebsiteClaim = "website"
EmailVerifiedClaim = "email_verified"
GenderClaim = "gender"
BirthdateClaim = "birthdate"
ZoneinfoClaim = "zoneinfo"
LocaleClaim = "locale"
PhoneNumberClaim = "phone_number"
PhoneNumberVerifiedClaim = "phone_number_verified"
UpdatedAtClaim = "updated_at"
clockSkew = 10 * time.Second
)
結果

なぜかnicknameが入ってくる。以下Keycloakのユーザー属性からnicknameを削除して再実行。


DB Field |
Claim |
変更 |
備考 |
name |
nickname | preferred_username |
不可 |
|
email |
email |
可 |
|
- 謎のnickname推し
-
Keycloakのユーザー情報にnickname属性が存在していると優先してusernameに使おうとするため、初回認証時のユーザー作成画面にnicknameが入るのを回避したい場合はそもそもnickname属性を作成してはいけない
- Keycloakでユーザー属性やマッパーにあれこれ設定してもフルネームには何も入れられない
CodiMD
- バージョン: 2.3.2 (Docker)
- 認証方式: SAML
Keycloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
CodiMD側のマッピング
docker-compose.yml
︙
- CMD_SAML_ATTRIBUTE_ID=id
- CMD_SAML_ATTRIBUTE_USERNAME=username
- CMD_SAML_ATTRIBUTE_EMAIL=email
︙
結果


DB Field |
SAML Attr |
変更 |
備考 |
profileId |
id |
不可 |
不可視, 識別に使用 |
profile.username |
username |
不可 |
表示名, ログイン時に更新 |
profile.emails |
email |
不可 |
不可視 |
-
表示名は認証の度に更新される
- もちろんusername以外のSAML Attributeを割り当てることもできる
- 運用中にマッピングを変更しても問題ない、内容は次の認証時に反映される
KeycloakのdisplayNameをCodiMDのusernameに割り当てた場合:

Wiki.js
- バージョン: 2.5 (Docker)
- 認証方式: SAML
KeyCloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Wiki.js側のマッピング

結果

DB Field |
SAML Attr |
変更 |
備考 |
providerId |
id |
不可 |
不可視, 識別に使用 |
name |
username |
可 |
表示名 |
email |
email |
可 |
|
- 表示名に任意のプロパティないし属性を紐付けられる
- Wiki.jsは標準ではメールアドレスとパスワードでログインする仕組みのためログインID的なものは存在しない
- 因みにWiki.jsにはKeycloak用のOAuth2の認証設定も存在する
Display Nameへのマッピングをnicknameに変更した場合:

GROWI
- バージョン: 4.2.12 (Docker)
- 認証方式: SAML
KeyCloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Prop |
firstName |
firstName |
Prop |
lastName |
lastName |
GROWI側のマッピング

結果

DB Field |
SAML Attr |
変更 |
備考 |
name |
firstName lastName |
可 |
表示名 |
email |
email |
可 |
|
- 表示名のフォーマットが
<firstName><半角スペース><lastName>
で固定されている
- firstNameやlastNameの値を空にすると
undefined
という文字列になって登録される
- 例えば
nickname [空文字列]
にすると ニックネーム undefined
になってしまう
- つまり表示名に単一の値を割り当てることができない
- 片方を
<remove this>
とかにしてユーザーに任せるくらいしか方法がない
- idの用途は不明
MongoDBに登録されたユーザー情報

Mattermost
- バージョン: 5.32.1 (Docker)
- 認証方式: OAuth2 (GitLab互換)
Keycloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Attr |
longId |
id |
Prop |
email |
email |
Prop |
username |
username |
Prop |
nickname |
name |
longIdについては Keycloak + Mattermost TE
のネタ元参照。今回は 12345
が入っている。
Mattermost側のマッピング
なし
結果


DB Field |
SAML Attr |
変更 |
備考 |
authdata |
id |
不可 |
不可視, 識別に使用 |
email |
email |
不可 |
|
username |
username |
不可 |
|
firstname |
name |
不可 |
表示名 |
- mention等に使われるusernameと表示名は分離しており、それぞれマッピングで個別に紐付けられる
- nameはfirstnameに投入され表示名になる
- Mattermost上ではユーザー情報は変更できず、Keycloak側で変更すると次の認証の際に同期される
- authdataに入るのはGitLabのユーザーID(gitlab.users.id: ユニークな整数)で、Mattermost側の認証に使用されているため重複や変更は不可
rocket.chat
- バージョン: 3.12.1 (Docker)
- 認証方式: SAML
Keycloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Attr |
nickname |
nickname |
rocket.chat側のマッピング
rocket.chat管理画面の「SAML → マッピング → ユーザーデータのフィールドマップ」
{
"email": "email",
"username": "username",
"name": "nickname",
"__identifier__": "id"
}
結果

DB Field |
SAML Attr |
変更 |
備考 |
id |
id |
不可 |
不可視, 識別に使用 |
username |
username |
可 |
表示名に設定可 |
name |
nickname |
可 |
表示名に設定可 |
email |
email |
可 |
|
- rocket.chatの管理画面から「レイアウト → ユーザーインターフェース → 実名を使用する」でチャット欄の表示名をusernameからnameに切り替えられる
- 設定画面の説明にある通り、姓名など任意のSAML Attrを組み合わせた上でフィールドに入れられる
- 優秀
MongoDBに登録されたユーザー情報

Wekan
- バージョン: 5.05.0 (Docker)
- 認証方式: OpenID Connect
Keycloak側のマッピング
Type |
Prop/Attr |
Claim Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Attr |
nickname |
nickname |
Wekan側のマッピング
︙
- OAUTH2_ID_MAP=id
- OAUTH2_USERNAME_MAP=username
- OAUTH2_FULLNAME_MAP=nickname
- OAUTH2_EMAIL_MAP=email
︙
結果

DB Field |
Claim Attr |
変更 |
備考 |
services.oidc.id |
id |
不可 |
識別用 |
username |
username |
設定可 |
|
profile.initial |
nickname |
可 |
先頭1文字? |
profile.fullname |
nickname |
可 |
表示名 |
emails[0].address |
email |
設定可 |
|
- イニシャルはデフォルトアバターに表示される文字列として使われる
- SAMLにも対応予定(ないし仮対応済)の模様
MongoDBに登録されたユーザー情報

TAIGA
- バージョン: 6.0.7 (Docker)
- 認証方式: OAuth2 (GitLab互換)
- 現状では
taiga-contrib-gitlab-auth
の実装に問題がありKeycloakと連携するにはソースの修正が必要
Keycloak側のマッピング
Type |
Prop/Attr |
Claim Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Attr |
nickname |
name |
TAIGA側のマッピング
なし
結果


DB Field |
Claim Attr |
変更 |
備考 |
username |
username |
可 |
mention等に使用 |
full_name |
name |
可 |
表示名 |
email |
email |
可 |
|
- mention等に使われるusernameと表示名は分離している
- 表示名にはOAuthの標準クレームの
name
が使用される(マッパーより優先される)
- Keycloakのユーザー情報の「姓」「名」から生成される、片方しか設定されていない場合は片方だけになる
- Keycloakのユーザー情報に「姓」も「名」も存在しない場合はマッパーでクレーム名
name
に紐付けた値が使用される
- idの用途は不明
PENPOT
- バージョン: 1.3.0-alpha-1 (Docker)
- 認証方式: OAuth2 (GitLab互換)
Keycloak側のマッピング
Type |
Prop/Attr |
Claim Attr |
Prop |
id |
id |
Prop |
email |
email |
Prop |
username |
username |
Prop |
nickname |
name |
Prop |
nickname |
fullname |
PENPOT側のマッピング
なし
結果


DB Field |
Claim Attr |
変更 |
備考 |
fullname |
name |
可 |
表示名 |
email |
email |
不可 |
|
- Claimに
name
と fullname
が両方存在している場合のみ name
が表示名として使われる
-
name
だけだったりなにも紐付けないと表示名は <firstName><半角スペース><lastName>
になる
- GitLabのOAuth2プロバイダーが
fullname
を持っているため、その辺の処理の都合っぽい
- 識別には
email
が使用されており、Keycloak側で変更すると別アカウント扱いになってしまう
-
id
は使われていない気がするし username
も行方不明、よくわからない
- まぁまだAlpha版だし……
NextCloud
- バージョン: 12.0.0.13 (Docker)
- 認証方式: SAML
Keycloak側のマッピング
Type |
Prop/Attr |
SAML Attr |
Prop |
email |
email |
Prop |
username |
username |
Attr |
nickname |
nickname |
NextCloud側のマッピング

結果


DB Field |
SAML Attr |
変更 |
備考 |
oc_user_saml_users.uid |
username |
不可 |
|
oc_user_saml_users.displayname |
nickname |
不可 |
表示名 |
? |
email |
不可 |
|
- 表示名に任意のプロパティ/属性を紐付けられる
- NextCloud上ではユーザー情報は変更できず、Keycloak側で変更すると次の認証の際に同期される