Microsoft Entra ID でディレクトリ拡張属性を使ってカスタムクレームを発行する方法

概要
Microsoft は、Entra ID(旧 Azure AD)のディレクトリ拡張属性を使って、ユーザー固有の追加データをサインイン処理でアプリに渡す方法を示しています。一般的な用途は、スポンサー情報や社内識別子など特定のユーザーグループにのみ付与したいメタデータを SSO トークンに含めることです。
この手順は次の流れです。
- アプリに対してディレクトリ拡張属性を登録する
- Graph API でユーザーオブジェクトに値を割り当てる
- エンタープライズアプリの Single Sign-On 設定でクレームを作成してグループ条件を設定する
- マッピングエラーが出た場合は一時的な対処を行う
- 実際にサインインしてトークンにクレームが含まれるか確認する
重要: 拡張属性の正式な名前は、登録後に “extension
前提条件
- Entra ID(Azure AD)管理者権限
- 対象アプリのアプリケーションオブジェクト ID とクライアント ID
- Microsoft Graph にアクセスできる Graph Explorer または適切なアクセストークン
- ユーザーをグループで管理していること(クレーム条件にグループを使う場合)
手順
ステップ 1: ディレクトリ拡張属性を登録する
Graph Explorer などから対象アプリケーションに対して拡張属性を登録します。例として sponsorid1 と sponsorid2 を登録します。
エンドポイント:
POST https://graph.microsoft.com/v1.0/applications/{AppObjectId}/extensionProperties
リクエストボディ例:
{
"name": "sponsorid1",
"dataType": "String",
"targetObjects": ["User"]
}
同様に sponsorid2 も登録してください。登録成功時に返る属性名は次のような形式です:
extension__sponsorid1
extension__sponsorid2
これらの正確な名前はメモしておきます。
ステップ 2: ユーザーに拡張属性を割り当てる
Graph API を使い、ユーザーオブジェクトを PATCH して拡張属性に値を入れます。
リクエスト例:
PATCH https://graph.microsoft.com/v1.0/users/{UserObjectId}
{
"extension__sponsorid1": "ABC123"
}
各ユーザーに対して必要な属性(sponsorid1 か sponsorid2)を割り当てます。
注意: 属性名は登録時に返された正確な文字列を使用してください。
ステップ 3: エンタープライズアプリでクレームを作成する
Entra ID 管理センターで次の操作を行います。
- Entra ID > Enterprise Applications > 対象アプリ > Single Sign-On > Attributes & Claims に移動
- [Add new claim] をクリック
- 名前例: sponsorClaim1 を入力
- Claim 条件では Member を選び、クレームを受け取るグループを指定
- ソース属性にディレクトリ拡張属性名(例: extension_
_sponsorid1)を設定
同様の手順で sponsorid2 を別グループにマッピングします。
ステップ 4: クレームマッピングエラーへの対応
エラー: “Application requires custom signing key to customize claims” が出る場合、短期的な回避策としてアプリ登録のマニフェストを更新できます。
マニフェスト例:
"acceptMappedClaims": true
この設定により、カスタム署名キーなしでクレームのカスタマイズを行えます。ただし、これは一時的な回避策です。長期運用では適切な署名キーとセキュリティ検討を行ってください。
重要: セキュリティ方針によりカスタム署名が必須の場合は、この回避は利用しないでください。
ステップ 5: 設定をテストする
ブラウザで次のような認可 URL を呼び出し、定義したグループに属するユーザーでサインインします。
https://login.microsoftonline.com/(Tenant ID)/oauth2/v2.0/authorize?client_id=(Client ID)&response_type=id_token&redirect_uri=https://jwt.ms&scope=openid&state=12345&nonce=12345
https://jwt.ms に表示されるトークン内に、期待したカスタムクレーム(sponsorid1 または sponsorid2)が含まれていることを確認します。定義外のグループに属するユーザーにはスポンサークレームは含まれません。
テストと検証のポイント
- グループメンバーシップが最新であること(Azure AD のグループ同期遅延に注意)
- 拡張属性の名称は正確に指定すること(大文字小文字を区別)
- SAML と OIDC での挙動の違いを確認(SAML の NameID/Attribute の扱いなど)
- jwt.ms や jwt.io で id_token をデコードしてクレームを検証
トラブルシューティング(よくある問題)
クレームがトークンに現れない
- 該当ユーザーが指定したグループに入っているか確認
- 拡張属性に値が入っているか Graph API で直接取得して確認
- アプリの Single Sign-On 設定で正しいソース属性を選んでいるか確認
“acceptMappedClaims” を設定してもエラーが残る
- マニフェストの反映に時間がかかる場合があります。変更後にアプリ再サインインを試す
- テナントのポリシーや CA(条件付きアクセスポリシー)でブロックされている可能性があるため、ポリシーを確認
属性値が古い/反映されない
- Graph の PATCH が成功したかレスポンスを確認
- キャッシュやトークンの有効期限の影響で古い値が返ることがある
役割別チェックリスト
ID 管理者:
- 拡張属性を登録し、正確な属性名を記録する
- テナントセキュリティポリシーに基づき acceptMappedClaims の利用可否を判断する
アプリオーナー:
- エンタープライズアプリでのクレーム設定とグループ条件を定義する
- トークン受け取り側の検証ロジックを実装する
セキュリティチーム:
- クレームに含める情報が過剰でないことを確認(個人情報や機密情報の管理)
- 必要に応じてカスタム署名キーの導入とローテーション手順を策定する
受け入れ基準
- グループ A のユーザーがサインインした際に、idtoken に extension
_sponsorid1 に対応するカスタムクレームが含まれる - グループ B のユーザーには sponsorid2 のクレームが含まれる
- グループに属さないユーザーにはいずれの sponsor クレームも含まれない
- 実運用でのセキュリティ要件(署名キー、ログ監査、最小権限)が満たされている
よくある失敗例と回避策
- 誤った属性名を使う: 登録結果の extension
… をコピーペーストして確実に使用する - グループ条件を間違える: クレーム条件はグループの Object ID を指定することを推奨
- 運用で acceptMappedClaims に頼りすぎる: 一時対応としては有用だが、長期はカスタム署名と正しいキー管理に移行する
処理フロー(図)
以下は高速な意思決定フローの例です。
flowchart TD
A[開始: 目的を定義] --> B{拡張属性を登録済みか}
B -- いいえ --> C[Graph API で登録]
B -- はい --> D[ユーザーに値を割当て]
C --> D
D --> E[エンタープライズアプリでクレーム作成]
E --> F{マッピングエラー発生?}
F -- はい --> G[acceptMappedClaims を検討]
F -- いいえ --> H[テストと検証]
G --> H
H --> I[本番移行と監査]
まとめ
Entra ID のディレクトリ拡張属性は、特定のユーザーグループに限定したカスタムクレームをトークンに含めたい場合に有効な手段です。Graph API を使った属性の登録とユーザー割当て、エンタープライズアプリ側でのクレーム作成、最後にトークンの検証を確実に行ってください。セキュリティ要件(署名キーや情報の取り扱い)を満たす運用設計を忘れずに行うことが重要です。
まとめチェック: 設定のドキュメント化、属性名の記録、テストユーザーでの検証、本番移行後の監査ログの確認を必ず行ってください。