Azure AD プロビジョニングとは?

Pocket

はじめに

本記事では、Azure AD が提供するサービスである ”プロビジョニング” について紹介していきます。本機能は非常にシンプルですが、本番環境で運用するにあたって知っておくと良いポイントをピックアップしてみたので、参考になれば嬉しく思います。

本記事のターゲットとスコープ

本記事では、Azure AD のプロビジョニングをこれから触る方々を対象に、機能の概要や、運用に役立つ情報をまとめた入門編です。

独自のアプリケーションに SCIM 2.0 のエンドポイントを実装することで Azure AD と連携することも可能ですが、プロフェッショナル向けの内容となるため、本記事のスコープ外としております。(需要があれば、別記事にてご紹介させてください。)

Azure AD のプロビジョニングってどんな機能?

はじめに 「プロビジョニング」という言葉の定義について認識を合わせておきましょう。プロビジョニングとは、利用者がサービスを利用できるように、ユーザー アカウントを作成したり、アクセス権限などの資源を割り当てる工程を総称した言葉だと私は考えています。

「では、Azure AD のプロビジョニングは、そういった機能を提供するサービスなの?」と聞かれると、間違っていはいないのですが少し違うような気がしています。

Azure AD のプロビジョニングは、下図のように、ソース システム (Azure AD) のユーザー アカウントを、ターゲット システム (SaaS アプリなど) にプロビジョニングする機能ですが、その後のライフ サイクル (更新・削除) にも対応していることから、どちらかという「同期サービス」という表現が適切です。

ユーザー プロビジョニング

なお、上図のように、アプリへのユーザー プロビジョニングを行うソリューションとして、たとえば、下記が考えられます。

  1. SAML JIT (Just-in-Time)
  2. Microsoft Graph API 経由でユーザー データを取得しプロビジョニングする。

SAML JIT は、SAML サインイン時に発行された SAML Response に含まれる Claim からユーザー属性を収集し、ユーザー アカウントの作成 および 更新を行うソリューションです。しかし、ユーザーの ”削除” には対応しておらず、サインインを必要としないグループは JIT で管理が行えません。

また、Microsoft Graph API 経由でユーザーのデータを収集することで、ユーザー アカウントの作成、更新、削除が行えますが、実装に要するコストが高くなる点が懸念されます。

一方で、本記事で紹介するプロビジョニングは、冒頭にお伝えしたようにいわゆる「同期サービス」であることから、SAML JIT よりも柔軟に管理が行えることに加えて、ターゲット システムが System for Cross-Domain Identity Management (SCIM) に準拠していれば、システム管理者は新たに実装する必要もありません。

最近では、多くの SaaS アプリが SCIM をサポートしていることから、本機能を使用してユーザー プロビジョニングを構成することが主流となってきました。

System for Cross-Domain Identity Management (SCIM) とは?

話が脱線するのですが、プロビジョニングの解説に入る前に、System for Cross-Domain Identity Management (SCIM) について少し触れておきます。

SCIM とは、ユーザー・グループのプロビジョニングのお作法を標準化したものでして、2015 年に改版された SCIM 2.0 が最新です。SCIM 2.0 の実装に関しては RFC 7643 と 7644 に目を通しておけば良いですが、Azure AD のプロビジョニングでは、基本的にプロトコルの中身を熟知しておく必要はないため、興味があれば覗くぐらいの気持ちで良いです。

Azure AD のプロビジョニングは SCIM 2.0 の API が実装されているため、言い換えると、SCIM 2.0 に準拠したアプリケーションでしたら簡単に Azure AD と連携することが可能です。自社アプリケーションに SCIM 2.0 を新たに実装するんだ!という方以外は、SCIM 2.0 の仕様を理解する必要はないのですが、プロビジョニング サービスの根幹には SCIM 2.0 が存在していることだけ認識しておいてください。

なお、プロビジョニングによる連携では必ずしも SCIM 2.0 の API が使用されているとは限りません。ターゲット システムとなるアプリの実装次第ですが、たとえば、ギャラリーに公開された Box アプリのプロビジョニングでは、Box の CRUD API を使用してプロビジョニングが構成されます。

プロビジョニングの動作のしくみを理解する

さて、ここからはプロビジョニングの技術的な部分に焦点を当てて見ていきましょう。まずは、どのようなしくみでターゲット システムにプロビジョニングが行われるのかを見ていきます。

下図はプロビジョニング エンジンの動作のフローを図示したものです。簡潔にお伝えすると、ソース/ターゲット システムからユーザー・グループを Import した結果をもとに Create (作成)、Update (更新)、Delete (削除) または スキップするのかを決定します。また、Import したユーザー・グループがプロビジョニング対象であるのかどうかを評価するフェーズや、ターゲット システムにどの属性をどのような値で Export するのかを決定するフェーズが間にあります。

Import

Import では、ソース システム (Azure AD) および ターゲット システムから、ユーザー・グループの情報をプロビジョニング サービスのデータベースに取り込みます。

Azure AD 側の Import では、Microsoft Graph API のエンドポイントを使用しますが、プロビジョニング ジョブが ”初回サイクル” か ”増分サイクル” かで取得する範囲が異なります。プロビジョニング ジョブの種別に関しては後述で解説します。

ターゲット システム側の Import では、アプリケーション側の実装に依存しますが、基本的には SCIM 2.0 の /Users および /Groups エンドポイントからユーザー・グループの情報を収集します。SCIM 2.0 に準拠したアプリであれば、 プロビジョニング サービスは下記のエンドポイントに GET メソッドを送信します。

  • GET /Users/5d48a0a8e9f04aa38008
  • GET /Users?filter=userName eq “Test_User_dfeef4c5-5681-4387-b016-bdf221e82081”

プロビジョニング サービスが送信するリクエストと、そのレスポンスは、次の公開情報にサンプルがあるので、興味があれば確認してみてください。

Scope Evaluation

Scope Evaluation では、Azure AD から Import したユーザー・グループがプロビジョニング対象であるかどうかを評価します。プロビジョニング サービスでは、下記 2 つの評価ロジックが存在します。

  1. 割り当てベースのフィルター
  2. スコープ フィルター

割り当てベースのフィルターとは、エンタープライズ アプリケーションの [ユーザーとグループ] をベースにフィルタリングする機能です。下図の場合ですと、DosExplorerUser01、DosExplorerUser02 および DosExplorer グループ メンバーのユーザーがターゲット システムにプロビジョニングされます。ターゲット システムがグループのプロビジョニングに対応している場合、 DosExplorer グループもプロビジョニングされます。

SCIM

割り当てベースのフィルターは既定で有効ですが、必要に応じて無効化することが可能です。具体的には、プロビジョニング メニューにある [範囲] を ”すべてのユーザーとグループを同期する” に変更することで割り当てベースのフィルターが無効化されます。

なお、割り当てベースのフィルターは以下の特徴を持ちます。下記の公開情報にも明記されているので、詳細はそちらをご参照ください。

  • 動的グループ メンバーシップ がサポートされます。
  • 入れ子になったグループはサポートされません。
  • [ユーザーとグループ] にグループを割り当てる場合は Azure AD Premium P1 以上のライセンスが必要です。

次に、スコープ フィルターとは、ユーザー・グループの属性値を条件にフィルタリングする機能です。たとえば、「Department (部署) が ”Sales” のみのユーザー アカウントをプロビジョニングする」といったルールが作成できます。スコープ フィルターがサポートする属性や演算子については次の公開情報をご確認ください。

まとめると、Scope Evaluation では、”割り当てベース” と ”スコープ フィルター” の 2 つで構成されています。Import された Azure AD ユーザーがスコープ内である場合はターゲット システムに Export されます。一方でスコープ外と評価された場合はターゲット システムには Export されません。

Attribute Mapping (属性マッピング)

プロビジョニング サービスでは、プロビジョニング スキーマに定義された内容に沿って、プロビジョニングする属性とその値が決定されます。 プロビジョニング スキーマ には、プロビジョニング対象の属性や、その型、Case Sensitive、必須かどうか、などといった情報に加えて、属性マッピングが定義されています。

属性マッピングでは、プロビジョニング対象の属性のソースとなる値を変更したり、関数を用いて変換したりと、柔軟にカスタマイズすることができる機能です。プロビジョニング メニューにある [マッピング] からユーザー・グループの属性マッピングが参照、変更できます。

SCIM

たとえば、SCIM 2.0 の必須属性である externalId のソース属性を ObjectId 属性に変更したりといったカスタマイズが可能です。

プロビジョニング

属性マッピングのカスタマイズは、実際の運用では割と利用する機会が多い機能ですので要チェックです。次の公開情報に詳細が記載されているので、こちらを参考にしてください。

ターゲット システムへの Export

プロビジョニング サービスは、ソース/ターゲット システムから Import した結果に従って、以下のいずれかの操作をターゲット システムに Export します。

  • 新規作成 (Create)
  • 更新/論理的な削除 (Update) ※論理的な削除はユーザーにのみサポートされます。
  • 削除 (Delete)

新規作成 (Create)

Azure AD ユーザーとマッチするユーザーがターゲット システムに存在しない場合、プロビジョニング サービスは、ターゲット システムにユーザーを作成するようリクエストを送信します。下図は、SCIM 2.0 に準拠するターゲット システムと Azure AD を連携した場合のフローです。

SCIM2.0

はじめに、プロビジョニング サービスは filter クエリを使用して、マッチするユーザーがターゲット システムに存在するかを確認します。マッチするユーザーがターゲット システムに存在しない場合、ターゲット システムはそのことをプロビジョニング サービスに伝えます。

ターゲット システムは、下記のように ListResponse をプロビジョニング サービスへ応答します。”totalResults: 0″ であることから、マッチするユーザーは存在しなかったことが分かります。

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "itemsPerPage": 1,
  "startIndex": 1,
  "totalResults": 0,
  "Resources": []
}

プロビジョニング サービスは、ターゲット システムにマッチするユーザーが存在しないことが分かると、ターゲット システムにユーザーを作成するようリクエストを送信します。リクエストの Body 部には下記のようにユーザーの属性情報が含まれます。なお、各属性の値はプロビジョニング スキーマに定義された設定 (属性マッピングなど) に従って決定されます。

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "externalId": "DosExplorerTest01",
  "userName": "DosExplorerTest01@contoso.com",
  "active": true,
  "displayName": "DosExplorerTest01",
  "emails": [
    {
      "primary": true,
      "type": "work",
      "value": "DosExplorerTest01@contoso.com"
    }
  ],
  "meta": {
    "resourceType": "User"
  },
  "name": {
    "formatted": "DosExplore Test01",
    "familyName": "Test01",
    "givenName": "DosExplore"
  },
  "title": "Manager",
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "department": "Sales"
  }
}

ターゲット システムはユーザーの各属性を収集しユーザー アカウントを作成します。エラーなく作成処理が完了しますと、作成されたユーザーの属性情報を newly user として Body 部に含めてプロビジョニング サービスに返します。なお、作成に何らかのエラーが生じた場合、ターゲット システムは SCIM Error をプロビジョニング サービスに通知します。

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "userName": "DosExplorerTest01@contoso.com",
  "displayName": "DosExplorerTest01",
  "id": "9726d56b-f975-4bd9-914c-0e1966777c5d",
  "externalId": "DosExplorerTest01",
  "active": true,
  "name": {
    "givenName": "DosExplore",
    "familyName": "Test01"
  },
  "emails": [
    {
      "type": "work",
      "primary": true,
      "value": "DosExplorerTest01@contoso.com"
    }
  ],
  "addresses": null,
  "phoneNumbers": null,
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "organization": null,
    "department": null,
    "employeeNumber": null
  },
  "meta": {
    "resourceType": "User",
    "created": "2021-07-24T18:17:12.403Z",
    "lastModified": "2021-07-24T18:17:12.403Z",
    "location": "https://directoryobjectservice.azurewebsites.net/scim/v2/Users/9726d56b-f975-4bd9-914c-0e1966777c5d"
  }
}

更新/論理的な削除 (Update)

次は、ユーザー・グループを更新するシナリオです。ターゲット システムにマッチするユーザーが存在している、且つ、Azure AD ユーザーとの差分がある場合、プロビジョニング サービスは属性値を更新するためにターゲット システムに PATCH メソッドを送信します。

SCIM

先程の filter クエリではなく、/Users/<Id> を使用してマッチするユーザーがターゲット システムに存在するかを確認します 。<Id> はターゲット システム側でユーザーが作成された際に生成される「オブジェクトを一意に識別するための属性」です。マッチするユーザーが見つかった場合、ターゲット システムはそのユーザーをプロビジョニング サービスへ返します。

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "userName": "DosExplorerTest01@contoso.com",
  "displayName": "DosExplorerTest01",
  "id": "9726d56b-f975-4bd9-914c-0e1966777c5d",
  "externalId": "DosExplorerTest01",
  "active": true,
  "name": {
    "givenName": "DosExplore",
    "familyName": "Test01"
  },
  "emails": [
    {
      "type": "work",
      "primary": true,
      "value": "DosExplorerTest01@contoso.com"
    }
  ],
  "addresses": null,
  "phoneNumbers": null,
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "organization": null,
    "department": "Sales",
    "employeeNumber": null
  },
  "meta": {
    "resourceType": "User",
    "created": "2021-07-24T18:17:12.403Z",
    "lastModified": "2021-07-24T18:17:12.403Z",
    "location": "https://directoryobjectservice.azurewebsites.net/scim/v2/Users/9726d56b-f975-4bd9-914c-0e1966777c5d"
  }
}

プロビジョニング サービスは、ソース/ターゲット システムから Import したユーザーの属性値を比較します。差分がある場合は、ソース システム、つまり、Azure AD ユーザーの属性値で上書き更新するために下記を Body 部に含めて PATCH メソッドを送信します。

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:PatchOp"
  ],
  "Operations": [
    {
      "op": "Add",
      "path": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber",
      "value": "ABCD1234"
    },
    {
      "op": "Replace",
      "path": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department",
      "value": "HumanResource"
    }
  ]
}

ターゲット システムは PATCH メソッドの内容を解析し、マッチしたユーザーの属性を更新します。更新処理が成功しますと、更新されたユーザー情報を Updated user として Body 部に含めて、プロビジョニング サービスに 200 OK を返します。

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "userName": "DosExplorerTest01@contoso.com",
  "displayName": "DosExplorerTest01",
  "id": "9726d56b-f975-4bd9-914c-0e1966777c5d",
  "externalId": "DosExplorerTest01",
  "active": true,
  "name": {
    "givenName": "DosExplore",
    "familyName": "Test01"
  },
  "emails": [
    {
      "type": "work",
      "primary": true,
      "value": "DosExplorerTest01@contoso.com"
    }
  ],
  "addresses": null,
  "phoneNumbers": null,
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "organization": null,
    "department": "HumanResource",
    "employeeNumber": "ABCD1234"
  },
  "meta": {
    "resourceType": "User",
    "created": "2021-07-24T18:17:12.403Z",
    "lastModified": "2021-07-24T18:17:12.403Z",
    "location": "https://directoryobjectservice.azurewebsites.net/scim/v2/Users/9726d56b-f975-4bd9-914c-0e1966777c5d"
  }
}

なお、プロビジョニング サービスは ”論理的な削除” をサポートします。論理的な削除とは、ターゲット システム側のアプリの実装によって解釈が異なりますが、一般的にはユーザーを完全に削除するのではなく、利用できないようにアカウントを無効化することを意味します。

プロビジョニング サービスでは、Azure AD のユーザーに対して下記の操作が行われますと、ターゲット システムに ”論理的な削除” を送信します。

  • ユーザーがプロビジョニングのスコープ外となった場合
  • ユーザーが Soft Delete (復元可能な削除) された場合
  • ユーザーが無効化 (AccountEnabled = false) された場合

プロビジョニング サービスが上記のいずれかを検知しますと、ターゲット システムに論理的な削除を送信します。論理的な削除は、実際にユーザー アカウントを削除するのではなく、active = false の更新をターゲット システムに送信するだけです。つまり、PATCH メソッドを使用してユーザー アカウントを更新しているだけです。

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:PatchOp"
  ],
  "Operations": [
    {
      "op": "Replace",
      "path": "active",
      "value": "False"
  ]
}

論理的な削除をサポートしないターゲット システムの場合、プロビジョニング サービスは次に説明する 削除 (Delete) の処理を行う場合があるため、SaaS 側の仕様も確認しておくと良いでしょう。論理的な削除については次の公開情報でも紹介しているので、こちらが参考になるかと思います。

削除 (Delete)

最後は、ユーザー・グループを削除するシナリオです。ターゲット システムにマッチするユーザーが存在しているが、Azure AD のユーザーが完全に削除された場合、プロビジョニング サービスはユーザーを削除するためにターゲット システムに DELETE メソッドを送信します。

プロビジョニング サービスでは、ユーザーが Hard Delete (完全に削除) された場合、ターゲット システムに DELETE メソッドを送信します。また、論理的な削除をサポートしないシナリオでは、スコープ外となった場合や、Soft Delete された時点で DELETE メソッドが送信されることがあります。

プロビジョニング ジョブのサイクル

次は、プロビジョニング ジョブのサイクルについて見ていきましょう。プロビジョニング ジョブでは、下記 2 つのサイクルが存在します。Azure AD Connect でいう完全同期、差分同期みたいなイメージですね。

  • 初回サイクル
  • 増分サイクル

それぞれのサイクルで処理内容が異なることに加えて、必要なタイミングで必要なサイクルを実行する必要があるため、システム管理者はそれぞれの違いをよく理解しておく必要があります。なお、次の公開情報にも詳しい情報が記載されているので、こちらも合わせてご覧ください。

初回サイクル

初回サイクルでは、ソース システム (Azure AD) のすべてのユーザー・グループ オブジェクトが取得、評価されます。具体的には、初回サイクルでは下記のステップで処理が行われます。

  1. ソース システム (Azure AD) のすべてのユーザー・グループを取得し、属性マッピングで定義されているすべての属性を取得します。
  2. Azure AD から返されたすべてのユーザー・グループに対して、プロビジョニングのスコープ対象か否かを評価します。
  3. スコープ内のユーザー・グループは、マッチするユーザー・グループがターゲット システムに存在するかを確認します。
  4. 一致するユーザーが見つからなかった場合はユーザーを作成し、見つかった場合は必要に応じて属性値を更新します。
  5. 初回サイクル終了時に、次回の増分サイクルの始点となるウォーターマーク (基準値) を生成、保持します。

初回サイクルの一番のポイントは、上記ステップ 1. の「ソース システムからの Import 処理」です。記載の通り、すべてのユーザー・グループを Azure AD から取得しスコープの評価を行うため、当然ですが、初回サイクルはパフォーマンスの低下に繋がります。

ただし、プロビジョニング スキーマ (属性マッピングなど) を変更した場合、それを反映させるためには初回サイクルを実行しなければならないため、システム管理者は必要に応じて実行します。

増分サイクル

増分サイクルは、初回サイクルが実行された後に定期実行されるサイクルです。その名の通り、前回の基準値から更新されたユーザー・グループのみをソース システムから取得します。具体的には、Microsoft Graph API の Delta クエリを使用します。

  1. 前回の基準値から更新されたユーザー・グループがいないかを Azure AD に問い合わせます。
  2. Azure AD から返されたユーザー・グループに対して、プロビジョニングのスコープ対象か否かを評価します。
  3. スコープ内のユーザー・グループは、マッチするユーザー・グループがターゲット システムに存在するかを確認します。
  4. 一致するユーザーが見つからなかった場合はユーザーを作成し、見つかった場合は必要に応じて属性値を更新します。
  5. 増分サイクルの終了時に、次回の増分サイクルの始点となるウォーターマーク (基準値) を生成、保持します。

初回サイクルとは異なり、前回の基準値から発生した更新のみを対象に Azure AD へクエリを送信します。このため、初回サイクルと比べてパフォーマンスが高いのが特徴です。

プロビジョニング のエラーとトラブル シューティング

ターゲット システム側のエラーが原因でユーザーの追加、更新、削除に失敗すると、それはエラーとしてカウントアップされていきます。加えて、そのエラーは次回のプロビジョニング サイクルでリトライが行われます。

エラーが一定数を超えた場合や、致命的なエラーが生じている場合は、次項に紹介する ”検疫” によってプロビジョニング サービスが停止することもあります。ここでは、プロビジョニングにエラーが生じた場合、システム管理者が行えるトラブルシューティング方法を簡単にご紹介します。

なお、既知の問題や、制約事項に関しては、次の公開情報にまとめられているので、まずはこちらに目を通しておくと良いかと思います。

たとえば、ターゲット システム側でユーザーの作成に失敗した場合、プロビジョニング サービスは下図のように進捗状況バーにそれを表示します。エラーがカウント アップされている場合は ”プロビジョニング ログ” からエラーを特定し解消する必要があります。

プロビジョニング

[プロビジョニング ログの表示] から、エラーの詳細を確認することが可能です。サービス プリンシパルの監査ログにも同等のログが確認できますが、プロビジョニング ログはユーザーに対する一連の処理を 1 つのログにまとめてくれているので、こちらのほうが見やすいです。

下図では、DosExplorerUser01 の Create (作成) が Failure していることに加えて、何度も再試行されている様子が確認できます。

プロビジョニング

エントリをクリックすると、そのログの詳細が確認できます。下図の場合、ターゲット システムから、何らかのエラーが応答されている状況が伺えます。

[トラブルシューティングと推奨事項] タブでは、ターゲット システムから応答されたエラー内容を確認することが可能です。スタック トレースをそのまま返しちゃってますが・・・ユニークキーに重複が発生しているため MongoError が応答されていることが分かりましたね。

なお、プロビジョニング ログの参照には、Azure AD Premium ライセンスがテナントに関連付けられている必要があります。ライセンスをお持ちでない方でもサービス プリンシパルの監査ログから同等の内容は見れますので、ご安心ください。

重複を修正後、次回の増分サイクルによってエラーが解消されると、進捗状況バーからエラーのカウント アップが削除されていることが確認できました。

プロビジョニング

プロビジョニング ジョブの検疫

プロビジョニング サービスでは、ターゲット システムの異常が検知されると、対象のプロビジョニング ジョブを検疫します。プロビジョニング ジョブが検疫されると、最終的にはプロビジョニング ジョブが停止するため、システム管理者は早急に問題を解消する必要があります。

  • 増分サイクルの頻度が減少し、最終的には 1 日 1 回となる。
  • 検疫状態が 4 週間を超えると、プロビジョニング ジョブは無効化される。

プロビジョニング ジョブは検疫されるシナリオとして下記の 4 つがあります。

  1. エラーのカウント アップがしきい値を超えてしまった。
  2. ターゲット システムから SCIM 2.0 に準拠しないレスポンスが応答された。
  3. ターゲット システムと接続するための資格情報が無効になっている。
  4. ターゲット システムからインポートされるロールに重複が生じている。

上記の 1. の ”しきい値” は、最低でも 5,000 個の失敗が必要です。詳しい条件は次の公開情報にまとめられているので、こちらをご参照ください。

また、4. は Salesforce や Zendesk など、ターゲット システムからロールを Import する場合があるシナリオのみに起こる少し特殊な例です。問題が発生した場合は重複するロールをアプリケーションのマニフェストから削除する必要があります。

プロビジョニング ジョブの検疫状態を解除するには?

プロビジョニング ジョブが検疫されると、増分サイクルの頻度が減少するため、言い換えると、ターゲット システムへのプロビジョニングが行われていない可能性があります。システム管理者は検疫されている原因を特定し解消したら、検疫から正常なステータスへと変更する必要があります。

検疫を解除するには、初回サイクルを手動で実行する方法 を実行する必要があります。詳細は後述に記載していますが、プロビジョニング ジョブを再起動することで検疫、エラーのカウント アップ数をクリアしてプロビジョニング ジョブを再開することが可能です。

プロビジョニング ジョブが検疫されたことを気づくには?

システム管理者は、プロビジョニング ジョブが検疫された場合、それを検知し対処する必要があります。検疫された場合、Azure Portal の進捗状況バーに警告メッセージが表示されますが、定期的にこれを監視することは運用として成立しないため、下記のいずれかを構成しておくことを推奨します。

  1. Microsoft Graph API からステータスを取得する。
  2. メール通知機能を有効化しておく。

進捗状況バーと同等の内容が Microsoft Graph API から取得することが可能です。具体的には、下記のエンドポイントから取得可能です。

  • GET https://graph.microsoft.com/beta/servicePrincipals/{サービス プリンシパルのオブジェクト Id}/synchronization/jobs/{プロビジョニングのジョブ Id}/

プロビジョニングのジョブ Id は、Azure Portal から確認することが可能です。

Microsoft Graph API は以下のようなレスポンスを応答します。status.code が ”Quarantine” であること、quarantine.reason が ”EncounteredQuarantineException” であることから、ターゲット システムに接続するための資格情報が無効であることが原因となり、検疫となっていますね。

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#servicePrincipals('fb50b6f2-ba43-4555-bc9b-c962e5a14490')/synchronization/jobs/$entity",
    "id": "scim.982337601031441c94b2fb2d6ac9d019.7898a79e-4d1f-4b04-a49c-ddc249eb1f72",
    "templateId": "scim",
    "schedule": {
        "expiration": null,
        "interval": "PT40M",
        "state": "Active"
    },
    "status": {
        "countSuccessiveCompleteFailures": 1,
        "escrowsPruned": false,
        "code": "Quarantine",
        "lastSuccessfulExecution": null,
        "lastSuccessfulExecutionWithExports": null,
        "steadyStateFirstAchievedTime": "0001-01-01T00:00:00Z",
        "steadyStateLastAchievedTime": "0001-01-01T00:00:00Z",
        "troubleshootingUrl": "",
        "lastExecution": {
            "activityIdentifier": "eb5fe7b3-1d01-410f-ad42-286272a39fb9",
            "countEntitled": 0,
            "countEntitledForProvisioning": 0,
            "countEscrowed": 0,
            "countEscrowedRaw": 0,
            "countExported": 0,
            "countExports": 0,
            "countImported": 0,
            "countImportedDeltas": 0,
            "countImportedReferenceDeltas": 0,
            "state": "Failed",
            "timeBegan": "2021-08-01T01:12:45.2943435Z",
            "timeEnded": "2021-08-01T01:13:45.6413156Z",
            "error": {
                "code": "SystemForCrossDomainIdentityManagementCredentialValidationFailure",
                "message": "While attempting to validate our authorization to access your application, we received this unexpected response:Received response from Web resource.   Resource:    Operation:     Response Status Code: RequestTimeout   Response Headers:    Response Content: A request timed out.  The request was to https://directoryobjectservice.azurewebsites.net/scim/v2.  The timeout was 60,000.00 millisecondsPlease check the service.  ",
                "tenantActionable": false
            }
        },
        "progress": [],
        "quarantine": {
            "currentBegan": "2021-08-01T01:13:45.6256765Z",
            "nextAttempt": "2021-08-01T01:18:45.6256765Z",
            "reason": "EncounteredQuarantineException",
            "seriesBegan": "2021-08-01T01:13:45.6256765Z",
            "seriesCount": 1,
            "error": {
                "code": "SystemForCrossDomainIdentityManagementCredentialValidationFailure",
                "message": "While attempting to validate our authorization to access your application, we received this unexpected response:Received response from Web resource.   Resource:    Operation:     Response Status Code: RequestTimeout   Response Headers:    Response Content: A request timed out.  The request was to https://directoryobjectservice.azurewebsites.net/scim/v2.  The timeout was 60,000.00 millisecondsPlease check the service.  ",
                "tenantActionable": false
            }
        },
        "synchronizedEntryCountByType": []
    },
    "synchronizationJobSettings": [
        {
            "name": "AzureIngestionAttributeOptimization",
            "value": "True"
        }
    ]
}

検疫を検知するもう 1 つの方法が、メール通知です。Azure Portal の [プロビジョニングの編集] – [設定] にある「エラーが発生したときにメール通知を送信します」にチェックをつけ、受信先となるメールアドレスを設定します。

プロビジョニング ジョブが検疫されると 1 日に 1 回だけ下図のようなメールが送信されます。

SCIM

なお、このメール通知機能は、あくまで検疫されたことを通知する機能である一方で、個別のエラーを通知する機能ではありません。個別のエラーも検知したいといったご要望がありましたら、プロビジョニング エラーが発生した場合にメール通知する をお試しください。

TIPS

ここでは、運用の中でお役に立てそうな機能をいくつかご紹介したいと思います。いずれもよく使う機能ですので、日々の運用の中に取り入れることを推奨します。

プロビジョニング スキーマのバックアップとロールバック

プロビジョニング スキーマとは、こちら でご紹介したように、プロビジョニング対象の属性や、その型、Case Sensitive、必須かどうか、などといった情報に加えて、属性マッピングが含まれた定義ファイルです。

たとえば、属性マッピングを Azure Portal から編集した場合、それに伴って、プロビジョニング スキーマも変更されます。言い換えると、設定変更前のプロビジョニング スキーマを持っていれば、以前の設定にロールバックすることが可能です。

プロビジョニング スキーマの内容に不備が生じると、場合によってはターゲット システムのサービス利用に影響を及ぼす可能性はあるので、作業前には必ずバックアップを行い、必要に応じてロールバックしましょう。

なお、プロビジョニング スキーマのバックアップとロールバックの方法は次の公開情報にまとめられているので、こちらが参考になるかと思います。

プロビジョニング エラーが発生した場合にメール通知する

プロビジョニング サービスのメール通知は、プロビジョニング ジョブが検疫された場合のにみ、1 日 1 回だけメール通知を行います。しかしながら、個々のプロビジョニング エラーを通知するような機能は実装されておりません。

個々のプロビジョニング エラーを通知するよう構成したい場合は、Azure Monitor による監視が適切です。プロビジョニング ログを Log Analytics に送信すれば、KQL クエリに合致するログが検出された場合はメール、SMS などで通知するよう構成することが可能です。

ここでは詳細は割愛しますが、次の公開情報にサンプルの KQL クエリがありますので、こちらが参考になるかと思います。

初回サイクルを手動で実行する方法

初回サイクルを手動で実行したいシナリオはいくつかあります。初回サイクルは Azure Portal または Microsoft Graph API から手動でトリガーさせることが可能です。

  • プロビジョニング スキーマの変更内容を反映させたい。
  • プロビジョニング ジョブの検疫・エラーをクリアしたい。
  • 発生した問題の原因の所在を切り分けたい。

Azure Portal からですと、[プロビジョニングを再開する] ボタンをクリックすること初回サイクルが実行されます。

[プロビジョニングを再開する] ボタンをクリックしますと、下記のタスクが実行されます。

  1. プロビジョニング サービスの再起動
  2. 初回サイクルのトリガー
  3. エラーのカウント アップをクリア
  4. 検疫状態のクリア

下記の resetScope を指定することで、Microsoft Graph API から同等の操作が行えます。

POST /servicePrincipals/{id}/synchronization/jobs/{jobId}/restart

{
   "criteria": {
       "resetScope": "Watermark, Escrows, QuarantineState"
   }
}

Microsoft Graph API の場合、resetScope に ”ConnectorDataStore” または ”Full” を指定することで CDS (Connector Data Store) のキャッシュ データを削除することが可能です。CDS にはこれまでターゲット システムにプロビジョニングされたユーザー・グループのキャッシュ データが格納されており、ソース システムとターゲット システム間のオブジェクトのリンク情報なども含まれています。

古いキャッシュ情報が起因して問題が生じている場合は CDS も含めてクリアすると問題は解消する見込みはありますが、キャッシュデータの削除に伴って他の問題に派生する可能性も否定できないので、このオプションは必要に応じて実施を検討ください。

特定ユーザーのみをプロビジョニングする方法

手動で増分サイクルを実行することは、残念ながらできません。しかしながら、日々の運用で次のようなシナリオは必ず発生してきます。

  • 問題のトラブルシューティングのために、特定ユーザーのプロビジョニングを実行したい。
  • プロビジョニング スキーマの変更後の動作テストを、特定ユーザーを対象に実施したい。
  • 急ぎで特定のユーザーをターゲット システムにプロビジョニングしたい。

こういったシナリオのために、オンデマンド プロビジョニングという機能が実装されています。この機能では特定の 1 ユーザーを対象に、ターゲット システムへすぐにプロビジョニングが行える機能です。詳細は次の公開情報をご確認ください。

なお、現在は 1 ユーザー単位でのみしか行えないため、グループ単位でのオンデマンド プロビジョニングは行なえません。今後の機能改善に期待です。

おわりに

いかがでしたでしょうか? Azure AD のプロビジョニングは簡単に構成が行えるためか、動作のしくみを把握している方々が少ないように思えます。しくみを理解しておくことで、問題が発生した時は円滑にトラブル シューティングが行えるので、これからプロビジョニングを構成する方々は是非本記事を参考にしていただければと思います。

それでは、よい Azure AD ライフをっ☺️

Pocket

コメントを残す

メールアドレスが公開されることはありません。