ご覧いただきありがとうございます。
皆様は RFC7644 SCIM と呼ばれる仕様はご存じでしょうか。 SCIMとは"System for Cross-domain Identity Management" の略で、システム間でのID管理を自動化する機能です。 この機能を実装すると、Microsoft Entra ID(旧Azure AD)やOktaなどのID管理システムでのユーザー情報の変更を自動的に連携先のシステムに反映させることができます。
Microsoft Entra IDやOktaなどId管理システムは連携用のカタログを公開しており、数クリックで連携させることができます。
本記事ではSCIMを実装するための要件検討からMicrosoft Entra ID, Oktaに申請するまでに必要な技術情報を扱います。 今実装しようとしているものが、Id管理システムのId供給側(Id Provider)の場合、他の情報源を当たるようにしてください。
用語について
- SCIM: SCIMとは"System for Cross-domain Identity Management" の略で、システム間でのユーザーや組織情報の同期を行うための仕様です
- Identity Provider(IdP): ユーザー・組織情報を提供する側のシステムを指します
- Serivce Provider(SP) : ユーザー・組織情報を利用する側のシステムを指します
- Microsoft EntraID: Microsoft Azure Active Directory(Azure AD)の新名称を指します。この文章では Microsoft EntraIDで統一しています
SCIMって?
SCIMは基本的なhttp + JSONメッセージのhttp APIで構成されます。概念図を下に示します。
1. 初期プロビジョニング
IdP/SP間でユーザーの存在確認を行います
GET /Users
リクエスト : SPのユーザーをすべて取得しますPOST /User
リクエスト : SPに存在しないユーザーを作成します
2. IdPで変更されたユーザー情報をSPへ差分適用する
GET /User/{id}
リクエスト : IdP/SP間で連携用のIDを使ってユーザーの存在を確認しますPUT /User/{id}
リクエスト : IdPで行われたユーザー情報の変更をSPに適用します
3. IdPで作成されたユーザーをSPにも作成する
GET /Users?filter=
リクエスト : IdPで作成されたユーザーがSPに存在するか確認しますPOST /User
リクエスト : IdPで作成されたユーザーをSPに作成します
連携目標のシステムを決める
前述のとおり超大手のID管理クラウドシステムは連携ギャラリーを公開しており、SCIMを実装することになったらギャラリー登録を目標にすると良さそうです。
Microsoft Entra ID, Okta以外にもプロビジョニング機能を持っているサービスは存在します。
- Microsoft Entra ID
- Okta
- OneLogin
- Google workspace
- Ping Identity
ギャラリーや開発支援ツールの充実度や参考にできるドキュメント量からMicrosoft Entra ID,Oktaをcybozu.comでは連携目標に定めました。
仕様を概観する
目標となる連携先を決めたら、仕様をざっくり理解していきましょう。よいドキュメントを公開してくれていますのでこちらを読んでざっくり理解します。
- Okta What is SCIM for?
- Okta and SCIM Version 2.0
- Azure Active Directory でのアプリケーションのプロビジョニングのしくみ
- チュートリアル: Azure Active Directory の SCIM エンドポイントのプロビジョニングを開発および計画する
ざっくり理解できたら必要に応じてRFCを読み込んでいくとよいでしょう。次にまとまっています。System for Cross-domain Identity Management
詳細なhttpリクエストやレスポンスボディの詳細は、上記ドキュメントによく書かれているので割愛します。
認証方法を決める
Id管理システムから開発しているWebシステムの認証方法を決めます。以下3点から、方針を決めるとよいでしょう。
- Id管理システムから利用可能な認証方式
- 開発中のWebシステムのアーキテクチャで実装可能
- できる限りセキュア
Id管理システムによっていくつかの認証方式が提供されています。例となる認証方式を次に示します。
- OAuth2.0プロトコル
- httpヘッダー + シークレットトークン
- ベーシック認証
OAuth2.0のプロトコルに沿ってで実装したかったのですが、弊社のアーキテクチャでは実装が困難でした。 このため、httpヘッダー+シークレットトークンによる認証を採用、実装しました。
実装する範囲を決める
実装する範囲を決めます。ユーザーだけでなくグループのプロビジョニングも仕様としては存在しています。 適宜、工数や開発システムと相談の上、実装範囲を決めましょう。
ユーザーのプロビジョニング機能を動作させるために実装したエンドポイントを次に示します。
POST /Users
(新規ユーザーの作成)GET /Users
(全ユーザーの取得)GET /Users?filter=...
(絞り込みを使った複数ユーザーの取得)GET /Users/{id}
(ユーザーの取得)PUT /Users/{id}
(ユーザーの更新)PATCH /Users/{id}
(ユーザーの更新)DELETE /Users/{id}
(ユーザーの削除)GET /Schemas
(スキーマ情報の取得)
連携するId管理システムによっては上記のAPIの中に不要なものもあります。要件の状況に応じて実装するAPIを決めるとよいでしょう。
スキーマ設計をする
Microsoft Entra ID とcybozuのユーザーのマッピングを次に示します。
Microsoft Entra ID ユーザー | SCIMユーザースキーマ | cybozuユーザー |
---|---|---|
IsSoftDeleted | active | 使用状態 |
displayName | displayName | 表示名 |
surname | name.familyName | 姓 |
givenName | name.givenName | 名 |
emails[type eq "work"].value | Emailアドレス | |
user-PrincipalName | externalId | SCIM 拡張ユーザー項目として新規に用意 |
mailNickName/onpremisessamaccountname/user-PrincipalName | userName | ログイン名 |
なし | id | SCIM 拡張ユーザー項目として新規に用意 |
なし | meta.created |
作成日時 |
なし | meta.lastModified |
更新日時 |
設定項目未定 | password | パスワード |
SCIMの仕様ではほかにもたくさん属性があります。開発するシステムに合わせて決めるとよいでしょう。
実装する
Id管理システムによって投げるリクエストに特徴があります。そのため注意が必要です。 次の例は同じPATCHリクエストです。各社で微妙に構造体が異なります。気持ちを強く持って実装することが必要です。
{ "schemas": [ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ], "Operations": [ { "op": "replace", "value": { "emails[type eq \"work\"].value": "TestBxfpl@test.microsoft.com" } } ] }
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "value": { "emails": [ { "value": "newvalue@cybozu.onmicrosoft.com", "type": "work" } ] } } ] }
複数社のId管理システムを対応すると共通仕様とは名ばかりではないかと叫びたくなる気持ちになります。 その気持ちを抑えながら実装しきることが大切です。逆説的ではありますがPATCH周りの細かい話でつまづくと完成は近いので、がんばりましょう。
やや古いAzure ADとの連携を想定するときには以下に目を通しておきましょう。健闘を祈ります。
試験する・インテグレーションする
自動試験ツールを提供されています。実際のID管理システムとインテグレーションして動作確認する前に利用できます。 連携想定のId管理システムと結合する前に自動試験ツールで動作確認しておいた方が賢明でしょう。
ローカルの開発環境で試験する場合はngrok が便利です。セキュリティ規約で社内ツールとして利用可能なツールか確認するようにしてください。
ギャラリーを公開している企業に申請する
ギャラリーへの登録を申請して作業を進めていきましょう。
ここからが一番大変で、時間がかかります。 (社内で協力してくれた皆様、ありがとう)
執筆 : @yokotaso