OpenID Connect (OIDC) 連携対応仕様
# 1. はじめに
本文書は、Kompira Enterprise 2.0の認証（ログイン）をOpenID Connect (OIDC)と連携可能にする拡張対応について、その仕様を記述したものである。
なお、原理的にはOIDCプロトコルに対応しているIDプロバイダであれば、KE 2.0と連携可能であるが、当初のサポートはMS Entra IDのみとし、動作確認もMS Entra IDのみを対象として実施する。
# 2. 仕様
## 2.1. ログイン・ログアウト
### 2.1.1. ログイン画面
OIDC連携設定が有効な場合、ログイン画面にOIDCログイン用のリンク（リンク名はOIDC連携設定オブジェクトの表示名）が表示される。リンクをクリックすると、連携先OIDCの認証フローが開始する。
![image.png](https://image.docbase.io/uploads/d21352d1-8361-4868-890e-c3c0dc06c196.png =WxH)
ログイン後はユーザーのホームにリダイレクトする。
### 2.1.2. ログアウト
OIDCユーザーでログインしている場合、ログアウトはOIDCのログアウトURLにリダイレクトし、IDプロバイダ側でログアウト処理が実施される。ログアウト後は、Kompiraのログイン画面に遷移する。
## 2.2. ユーザーモデル
### 2.2.1. ユーザー情報の拡張
ユーザーモデルを拡張し、OpenID Connectによるユーザーであることを示すフィールドを以下のように追加する。
| フィールド名 | フィールド型 | 内容 | 備考 |
| --- | --- | --- | --- |
| oidc_provider | Object\<OidcProvider\> | 連携対象のOIDCプロバイダオブジェクト | ReadOnlyフィールド |
### 2.2.2. ユーザー名（ID）に使用できる文字の拡張
メールアドレスのlocal-partをKompiraのユーザー名としてそのまま利用できるようにするため、ユーザー名に使用できる文字を以下のように拡張する。
- 最大64文字
- 使用可能な文字はアルファベット、数字、下線(`_`)、ドット(`.`)、ハイフン(`-`)
- ドットは先頭、末尾には置けない。また、連続することはできない。
- 先頭の数字は許可する。

※ RFCの規定ではlocal-partの制限は上記よりもさらに緩い（`$`、`!`、などその他の特殊記号も使用可能）が、多くのWebメールサービスでは、上記のような制限を課しているので、それに倣う。
> 現状は、最大30字、アルファベット、数字、下線(`_`)のみ使用可能。数字を先頭に置くことは不可。（ジョブフロー言語の識別子やオブジェクト名と同じ制限）
#### ■ ホームディレクトリ作成時のディレクトリ名の自動変換
ホームディレクトリは `/home/<ユーザー名>` に作成されるが、ユーザー名で使用できる文字種を拡張することによって、Kompira オブジェクトの命名規則の制限に抵触する可能性がある。その場合、抵触する文字を下線（`_`）に置き換えてホームディレクトリを作成する。また、すでに同名のホームディレクトリが存在する場合は、衝突を避けるために、ディレクトリ名に連番のサフィックスを付加して作成する。
### 2.2.3. Kompiraユーザーとの紐づけ
LDAP連携と同様に、初回OIDCログイン時に当該ユーザーが存在しない場合、KE上にユーザーモデルを作成する。すでに同名のユーザーがローカルに存在する場合や、異なるOIDCプロバイダによるユーザーが存在する場合は、ログインエラーとする。

ユーザー作成時に使用されるユーザー名は、IDクレームに含まれる `preferred_username` フィールドの値とする。（このフィールドの値がメールアドレス形式になっている場合、local-part の部分のみを使用する）

IDクレームの `email`フィールドの値は、ユーザーモデル上のEメールアドレスフィールドに設定される。また、IDクレームに`family_name`、`given_name`フィールドが含まれる場合は、ユーザーモデルの`last_name`、`first_name`フィールドにそれぞれ値が設定される。
### 2.2.4. グループとロールのマッピング
IDクレームに`roles`フィールドが含まれ、かつ、連携設定でグループ変換辞書が設定されている場合、`roles`フィールドに含まれている値をKE上のグループに変換し、ユーザーに割り当てる。変換辞書に設定されているグループが`roles`に含まれない場合は、グループの割当を削除する。`roles`フィールドの値が変化することもあるため、この処理はログインの度に行う。
グループ変換辞書が設定されている場合は、ユーザーによる手動でのグループの割当ては禁止（フォームのグループフィールドを disabled に設定）する。設定されていない場合は、手動でのグループ割り当ての変更は可能とする。
> Azure で IDクレームに `roles` を含めるには、Azureのアプリケーション固有の設定で、クレームを編集し、属性としてロールやグループを追加しておく必要がある。クレームにロールを追加するには、Azure のアプリ登録の管理から「トークン構成」を開き、グループ要求を追加して、IDにグループ要求を含めるように設定しておく。
### 2.2.5. 許可グループ
KE にログイン可能なユーザーを特定の`roles`に制限したい場合、OIDC連携設定にて許可グループの設定を行う。そこに列挙されたロールが割り当てられているユーザーのみログインを許可する。
#### ※ ログインするユーザーを制限する方法
ログインユーザーを組織内のユーザー全てに許可するのではなく、一部のユーザーに制限するには、上記のように許可グループを設定する以外にも以下の方法がある。
- Azure に登録したKEアプリケーションのプロパティで「割当が必要ですか？」の項目を「はい」に設定する。このようにすると、「ユーザーとグループ」の管理項目で明示的に割り当てたユーザー、グループのみ、KEにログインできる。
## 2.3. 連携設定
### 2.3.1. OIDCプロバイダ(OidcProvider)型
以下のフィールドを持つ OIDC プロバイダ型を新規に導入する。
| フィールド名 | 型 | 意味 | 備考 |
| --- | --- | --- | --- |
| client_id (クライアントID) | String | クライアントID |  |
| client_secret (クライアントシークレット) | Password | クライアント秘密鍵 |  |
| oidc_endpoint (OIDCエンドポイント) | URL | OIDCプロバイダのエンドポイント | `<oidc_endpoint>/.well-known/openid-configuration`にアクセスして、各種エンドポイントを取得する |
| enable_sso(SSO有効化) | Boolean | シングルサインオン(SSO)を有効化する | デフォルトはfalse  |
| username_attr (ユーザー名属性) | String | ユーザー名として使用する属性 |  |
| group_mapping (グループ変換) | Dictionary | グループ変換の辞書 | キーにOIDCのロール、値に対応するKEのグループ名を指定する  |
| allow_groups(許可グループ) | Array | KEへのログインを許可するグループ |  |
/system/oidc_providersにOIDCプロバイダ型のテーブルを定義し、その配下に各種OIDCプロバイダの設定を作成する。

※ SSO有効化した場合、すでに同じブラウザでサインインしている場合は、ログイン時のアカウントとパスワード入力が省略される。
### 2.3.2. /system/configの項目追加
/system/configに以下の項目（フィールド）を追加する
| フィールド名 | 型 | 意味 | 備考 |
| --- | --- | --- | --- |
| oidcProvider (OIDCプロバイダ) | OidcProvider | ユーザー認証に利用するOIDCプロバイダ | 未設定の場合はローカル認証のみ |
## 2.4. その他
### 2.4.1. パスワードロック
Kompira側で提供しているパスワードロック機能は、Open ID Connect連携のユーザーに対しては無効である。必要に応じて連携先のOpen ID Connectプロバイダが提供しているパスワードロックを使用する。
### 2.4.2. フォールバックログイン
OIDCユーザーの場合、フォールバックログインは行わない。したがって、ネットワーク障害などによって OIDCプロバイダにアクセスできない場合、ログインできなくなる。
（OIDCユーザーの入力したパスワードはログイン時にローカルに保存されないため）
### 2.4.3. REST API
OIDCユーザーも通常のユーザーと同様、REST APIを有効にすることが可能である。トークンを用いてREST APIによるアクセスを行うことができる。
### 2.4.5. セッションの有効期間
ログインセッションの有効期間は、ローカルユーザーの場合、2週間（=336時間）だが、OIDCユーザーの場合も同様である。
### 2.4.6. パスワードの変更禁止
OIDCユーザーは、KEv2のユーザー編集画面からパスワードを変更することはできない。
パスワードの変更はOIDCプロバイダから行う。
# 3. 制限事項等
## 3.1. リダイレクト URL
OIDC プロバイダによっては、Redirect URL で指定可能なスキーマが https のみの場合がある。また、IPアドレスによる Redirect URL の登録ができない場合もある。
# 4. 参考情報
## 4.1. Django向けOIDC認証ライブラリ
実装には、以下に示すDjango向けの OIDC 認証ライブラリを利用する。
- social-auth-app-django
https://pypi.org/project/social-auth-app-django/
