チュートリアル: Azure Active Directory の SCIM エンドポイントのプロビジョニングを開発および計画する

アプリケーション開発者は System for Cross-Domain Identity Management (SCIM) ユーザー管理 API を使用して、アプリケーションと Azure Active Directory (Azure AD) の間のユーザーとグループの自動プロビジョニングを有効にできます。 この記事では、SCIM エンドポイントを構築し、Azure AD プロビジョニング サービスと統合する方法について説明します。 SCIM 仕様では、プロビジョニングのための共通のユーザー スキーマが提供されます。 SAML や OpenID Connect などのフェデレーション標準とともに使用した場合、SCIM では エンドツーエンドの標準ベースのアクセス管理用ソリューションが管理者に提供されます。

SCIM を使用した Azure AD からアプリへのプロビジョニング

SCIM 2.0 は、2 つのエンドポイント (/Users エンドポイントと /Groups エンドポイント) の標準化された定義です。 オブジェクトの作成、更新、および削除を行う共通の REST API エンドポイントを使用します。 SCIM は、グループ名、ユーザー名、名、姓、電子メールなどの一般的な属性の定義済みのスキーマで構成されています。

SCIM 2.0 REST API を提供するアプリでは、独自のユーザー管理 API を使用する煩わしさを軽減するか、なくすことができます。 たとえば、準拠している SCIM クライアントは、JSON オブジェクトの HTTP POST を /Users エンドポイントに送信して新しいユーザー エントリを作成する方法を認識しています。 同じ基本的なアクションに対して若干異なる API を必要とするのではなく、SCIM 標準に準拠しているアプリでは、既存のクライアント、ツール、およびコードをすぐに利用できます。

SCIM 2.0 (RFC 764276437644) で定義されている管理用の標準ユーザー オブジェクト スキーマと REST API を使用すると、ID プロバイダーとアプリをより簡単に相互に統合できます。 SCIM エンドポイントを構築するアプリケーション開発者は、カスタム作業を行わなくても、SCIM 準拠の任意のクライアントと統合できます。

アプリケーションへのプロビジョニングを自動化するには、Azure AD Provisioning Service によってアクセスされる SCIM エンドポイントを構築して統合する必要があります。 アプリケーションへのユーザーとグループのプロビジョニングを開始するには、次の手順を使用します。

  1. ユーザーとグループのスキーマを設計します。アプリケーションのオブジェクトと属性を特定し、それらが Azure AD SCIM 実装でサポートされているユーザーとグループのスキーマにどのようにマップするかを見極めます。

  2. Azure AD SCIM の実装を理解します。SCIM プロトコル要求の処理と応答をモデル化するために Azure AD プロビジョニング サービスを実装する方法を理解します。

  3. SCIM エンドポイントを構築します。エンドポイントは、Azure AD プロビジョニング サービスと統合するために、SCIM 2.0 と互換性がある必要があります。 オプションとして、Microsoft 共通言語基盤 (CLI) ライブラリとコード サンプルを使用してエンドポイントを構築します。 これらのサンプルは、参照とテストのみを目的としています。実稼働アプリの依存関係として使用することはお勧めしません。

  4. SCIM エンドポイントを Azure AD プロビジョニング サービスと統合します。 自分の組織でサードパーティ製のアプリケーションを使用して、Azure AD でサポートされる SCIM 2.0 のプロファイルを実装している場合、ユーザーとグループのプロビジョニングとプロビジョニング解除の両方をすぐに自動化することができます。

  5. [省略可能] Azure AD アプリケーション ギャラリーにアプリケーションを発行します。お客様がアプリケーションを簡単に検出し、プロビジョニングを簡単に構成できるようにします。

SCIM エンドポイントを Azure AD に統合する貯めに必要な手順を示す図。

ユーザーとグループのスキーマを設計する

アプリケーションはそれぞれ、ユーザーまたはグループを作成するためのさまざまな属性を必要とします。 アプリケーションで必要なオブジェクト (ユーザー、グループ) および属性 (名前、マネージャー、役職など) を特定して、統合を開始します。

SCIM 標準では、ユーザーとグループを管理するためのスキーマが定義されています。

コア ユーザー スキーマに必要な属性は 3 つだけです (それ以外の属性はすべて省略できます)。

  • id (サービス プロバイダーが定義した識別子)
  • userName (ユーザーの一意識別子。通常、Azure AD ユーザー プリンシパル名にマップされます)
  • meta (サービス プロバイダーによって管理される読み取り専用のメタデータ)

コア ユーザー スキーマに加えて、SCIM 標準では、エンタープライズ ユーザー拡張機能と、アプリケーションのニーズに合わせてユーザー スキーマを拡張するためのモデルが定義されています。

たとえば、アプリケーションでユーザーのメールとマネージャーの両方が必要な場合は、コア スキーマを使用してユーザーのメールを収集し、エンタープライズ ユーザー スキーマを使用してユーザーのマネージャーを収集します。

スキーマを設計するには、次の手順に従います。

  1. アプリケーションに必要な属性を一覧表示し、認証に必要な属性 (loginName や電子メールなど) として分類します。 属性は、ユーザーのライフサイクル (状態やアクティブなど) と、アプリケーションの動作に必要なその他すべての属性 (マネージャー、タグなど) を管理するために必要です。

  2. これらの属性がコア ユーザー スキーマまたはエンタープライズ ユーザー スキーマで既に定義されているかどうかを確認します。 定義されていない場合は、欠けている属性をカバーする拡張機能をユーザー スキーマに対して定義する必要があります。 ユーザー tag をプロビジョニングできるようにする、ユーザーに対する拡張機能については、以下の例を参照してください。

  3. SCIM 属性を Azure AD のユーザー属性にマップします。 SCIM エンドポイントで定義した属性のいずれにも、Azure AD ユーザー スキーマに明確に対応するものがない場合、テナント管理者にスキーマの拡張を求めるか、次の例に示す拡張属性を tags プロパティに使用します。

次の表に、必要な属性の例を示します。

アプリの必須属性 対応する SCIM の属性 対応する Azure AD の属性
loginName userName userPrincipalName
firstName name.givenName givenName
lastName name.familyName surName
workMail emails[type eq "work"].value Mail
manager manager manager
tag urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User:tag extensionAttribute1
status active isSoftDeleted (ユーザーに格納されない計算値)

次の JSON ペイロードは、SCIM スキーマの例を示しています。

{
     "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
      "urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User"],
     "userName":"bjensen@testuser.com",
     "id": "48af03ac28ad4fb88478",
     "externalId":"bjensen",
     "name":{
       "familyName":"Jensen",
       "givenName":"Barbara"
     },
     "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
     "Manager": "123456"
   },
     "urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User": {
     "tag": "701984",
   },
   "meta": {
     "resourceType": "User",
     "created": "2010-01-23T04:56:22Z",
     "lastModified": "2011-05-13T04:42:34Z",
     "version": "W\/\"3694e05e9dff591\"",
     "location":
 "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
   }
}   

Note

アプリケーションに必要な属性に加えて、JSON の表現には、必要な idexternalIdmeta の各属性も含まれています。

これによって /User/Group とに分類され、Azure AD における既定のユーザー属性を SCIM RFC にマップしやすくなります。Azure AD と SCIM エンドポイントの間で属性マッピングをカスタマイズする方法に関するページを参照してください。

次の表に、ユーザー属性の例を示します。

Azure AD ユーザー urn:ietf:params:scim:schemas:extension:enterprise:2.0:User
IsSoftDeleted active
department urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department
displayName displayName
employeeId urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber
Facsimile-TelephoneNumber phoneNumbers[type eq "fax"].value
givenName name.givenName
jobTitle title
mail emails[type eq "work"].value
mailNickname externalId
manager urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager
mobile phoneNumbers[type eq "mobile"].value
postalCode addresses[type eq "work"].postalCode
proxy-Addresses emails[type eq "other"].Value
physical-Delivery-OfficeName addresses[type eq "other"].Formatted
streetAddress addresses[type eq "work"].streetAddress
surname name.familyName
telephone-Number phoneNumbers[type eq "work"].value
user-PrincipalName userName

次の表に、グループ属性の例を示します。

Azure AD グループ urn:ietf:params:scim:schemas:core:2.0:Group
displayName displayName
members members
objectId externalId

注意

ユーザーとグループの両方をサポートする必要はありません。ここに記載されているすべての属性をサポートする必要もありません。これはあくまで参考として、Azure AD の属性が多くの場合どのように SCIM プロトコルのプロパティにマップされるかを示したものです。

SCIM RFC では複数のエンドポイントが定義されています。 /User エンドポイントで開始し、そこから展開できます。 次の表に、いくつかの SCIM エンドポイントを示します。

エンドポイント 説明
/User ユーザー オブジェクトに対して CRUD 操作が実行されます。
/Group グループ オブジェクトに対して CRUD 操作が実行されます。
/Schemas 各クライアントおよびサービス プロバイダーによってサポートされている属性のセットは、異なる場合があります。 たとえば、あるサービス プロバイダーに nametitleemails が含まれ、別のサービス プロバイダーに nametitlephoneNumbers が使用されることがあります。 スキーマ エンドポイントにより、サポートされている属性を検出できます。
/Bulk 一括操作を使用すると、1 回の操作でリソース オブジェクトの大きなコレクションに対する操作を実行できます (たとえば、大きなグループのメンバーシップの更新)。
/ServiceProviderConfig サポートされているリソースや認証方法など、サポートされている SCIM 標準の機能についての詳細が提供されます。
/ResourceTypes 各リソースに関するメタデータを指定します。

注意

カスタム属性をサポートする場合やスキーマが頻繁に変更される場合は、/Schemas エンドポイントを使用してください。クライアントで最新のスキーマを自動的に取得できます。 グループをサポートするには、/Bulk エンドポイントを使用します。

Azure AD SCIM の実装について

このセクションでは、SCIM 2.0 ユーザー管理 API をサポートするために、Azure AD プロビジョニング サービスの実装方法について説明すると共に、SCIM プロトコル要求の処理と応答のモデル化方法を紹介します。

重要

Azure AD SCIM の実装の動作は、2018 年 12 月 18 日に最終更新が行われました。 変更点については、Azure AD ユーザー プロビジョニング サービスの SCIM 2.0 プロトコルへのコンプライアンスに関する記事をご覧ください。

SCIM 2.0 プロトコル仕様の中で、アプリケーションは次の要件をサポートする必要があるとされています。

要件 参考 (SCIM プロトコル)
ユーザーを (必要に応じてグループも) 作成する セクション 3.3
PATCH 要求でユーザーまたはグループを変更する セクション 3.5.2. サポートにより確実に、パフォーマンスの高い方法でグループとユーザーがプロビジョニングされます。
以前に作成したユーザーまたはグループの既知のリソースを取得する セクション 3.4.1
ユーザーまたはグループを照会する セクション 3.4.2 既定では、ユーザーの取得には id、ユーザーのクエリには usernameexternalId、グループのクエリには displayName が使用されます。
グループ リソースの照会時に、フィルター excludedAttributes=members を使用する セクション 3.4.2.2
ユーザーの一覧表示とページ番号付けをサポートする セクション 3.4.2.4.
ユーザー active=false の論理削除とユーザー active=true の復元を行う ユーザーがアクティブかどうかに関係なく、要求でユーザー オブジェクトが返される必要があります。 ユーザーが返されないのは、アプリケーションから完全削除されているときです。
/Schemas エンドポイントをサポートする セクション 7 スキーマ検出エンドポイントは、追加の属性を検出する際に使用されます。
アプリケーションに対する Azure AD の認証と承認のために、単一のベアラー トークンを受け入れる。

Azure AD との互換性を確保するために、SCIM エンドポイントの実装時は次の一般的なガイドラインに従ってください。

全般:

  • id は、すべてのリソースの必須のプロパティです。 リソースを返すすべての応答において、メンバーが 0 の ListResponse を除き、各リソースにこのプロパティが含まれるようにする必要があります。
  • 送信された値は、送信時と同じ形式で格納する必要があります。 無効な値は、わかりやすいアクション可能なエラー メッセージを付けて拒否する必要があります。 データの変換は、Microsoft Azure Active Directory によって送信されるデータと SCIM アプリケーションに格納されているデータの間で行うことはできません。 (例: (55555555555 として送信された電話番号は、+5 (555) 555-5555 として保存または返すことはできません)
  • PATCH 応答には、リソース全体を含める必要はありません。
  • セクション 3.5.2 に定義されているように、特に PATCHop 操作値の場合、SCIM 内の構造要素に対して大文字と小文字を区別した一致を要求しないでください。 Azure AD では、op の値が AddReplaceRemove として出力されます。
  • Microsoft Azure AD では、エンドポイントと資格情報が有効であることを確認するため、ランダムなユーザーとグループをフェッチする要求を行います。 Azure portal 内で、テスト接続フローの一部としても行われます。
  • SCIM エンドポイントで HTTPS をサポートします。
  • カスタムの複合属性と複数値属性がサポートされますが、このような場合のデータのプル元となる複雑なデータ構造は、Azure AD には多くありません。 単純な名前と値型のペアの複合属性は簡単にマップできますが、現時点では、3 つ以上のサブ属性を持つ複合属性にデータをフローする方法は十分にサポートされていません。
  • 複数値を持つ複合属性の "type" サブ属性の値は一意である必要があります。 たとえば、サブタイプが "work" の 2 つの異なるメール アドレスを使用することはできません。
  • すべての応答のヘッダーは、content-Type: application/scim+json である必要があります

リソースの取得:

  • クエリ/フィルター要求への応答は常に ListResponse である必要があります。
  • Microsoft Azure AD では、演算子として eqand のみが使用されます。
  • リソースの照会が可能な属性は、Azure portal 内でアプリケーション上の照合属性として設定される必要があります。ユーザー プロビジョニング属性マッピングのカスタマイズに関するページを参照してください。

/Users:

  • エンタイトルメント属性はサポートされていません。
  • ユーザーの一意性のために使用される属性が、フィルター選択されたクエリの一部として使用できる必要があります。 たとえば、ユーザーの一意性が、userName と emails[type eq "work"] の両方に対して評価される場合、フィルターを使用した /Users への GET は、userName eq "user@contoso.com" クエリと emails[type eq "work"].value eq "user@contoso.com" クエリの両方に対して許可される必要があります。

/Groups:

  • グループはオプションですが、SCIM 実装で PATCH 要求がサポートされている場合にのみ、サポートされます。
  • Azure AD および SCIM アプリケーションと一致させるには、グループが一意の "displayName" 値を持っている必要があります。 この一意性は、SCIM プロトコルの要件ではありませんが、SCIM エンドポイントを Azure AD に統合するための要件です。

/Schemas (スキーマ検出):

  • 要求/応答のサンプル
  • スキーマの検出は、カスタムのギャラリー外 SCIM アプリケーションでは現在サポートされていませんが、特定のギャラリー アプリケーションでは使用されます。 今後は、既存のギャラリー SCIM アプリケーションのスキーマに属性を追加するための唯一の手段としてスキーマ検出が使用されます。
  • 値が存在しない場合は、null 値を送信しないでください。
  • プロパティ値はキャメル ケース (例: readWrite) にする必要があります。
  • リストの応答を返す必要があります。
  • だれかが Azure portal でプロビジョニング構成を保存するたび、または、ユーザーが Azure portal のプロビジョニング編集ページにアクセスするたび、Azure AD プロビジョニング サービス クライアントから /schemas 要求が送信されます。 その他の検出された属性は、[対象の属性] リストにある属性マッピングでお客様に示されます。 スキーマ検出では、対象の属性が新たに追加されるだけです。 属性が削除されることはありません。

ユーザーのプロビジョニングとプロビジョニング解除

次の図は、アプリケーションの ID ストア内にあるユーザーのライフサイクルを管理するために Azure AD から SCIM エンドポイントに送信されるメッセージを示しています。

ユーザーのプロビジョニング解除シーケンスを示す図。

グループのプロビジョニングとプロビジョニング解除

グループのプロビジョニングとプロビジョニング解除はオプションです。 実装され有効にされている場合、次の図は、アプリケーションの ID ストア内にあるグループのライフサイクルを管理するために Azure AD から SCIM エンドポイントに送信されるメッセージを示しています。 それらのメッセージは、次の 2 つの点でユーザーに関するメッセージと異なっています。

  • グループを取得する要求では、要求に対する応答の中で提示されるリソースから、members 属性が除外されるように指定しています。
  • 参照属性に特定の値があるかどうかを判別する要求は、members 属性に関する要求になります。

次の図は、グループのプロビジョニング解除シーケンスを示しています。

グループのプロビジョニング解除シーケンスを示す図。

SCIM プロトコル要求と応答

この記事では、Azure Active Directory (Azure AD) プロビジョニング サービスによって出力される SCIM 要求の例と、予想される応答の例を示します。 最良の結果を得るには、このような要求をこの形式で処理し、想定される応答を出力するよう、アプリをコーディングしてください。

重要

Azure AD ユーザー プロビジョニング サービスが以下に示す操作を出力する方法とタイミングについては、「プロビジョニング サイクル: 初回と増分」を参照してください。これは「プロビジョニングのしくみ」に含まれるセクションです。

ユーザー操作

グループ操作

スキーマ検出

ユーザー操作

  • ユーザーは userName または emails[type eq "work"] 属性でクエリすることができます。

[Create User]

Request

POST /Users

{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User",
        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
    "externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
    "userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
    "active": true,
    "emails": [{
        "primary": true,
        "type": "work",
        "value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com"
    }],
    "meta": {
        "resourceType": "User"
    },
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName"
    },
    "roles": []
}
Response

HTTP/1.1 201 Created

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "48af03ac28ad4fb88478",
    "externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com",
        "type": "work",
        "primary": true
    }]
}

ユーザーの取得

Request

GET /Users/5d48a0a8e9f04aa38008

応答 (ユーザー検出)

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "5d48a0a8e9f04aa38008",
    "externalId": "58342554-38d6-4ec8-948c-50044d0a33fd",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_feed3ace-693c-4e5a-82e2-694be1b39934",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_22370c1a-9012-42b2-bf64-86099c2a1c22@testuser.com",
        "type": "work",
        "primary": true
    }]
}
Request

GET /Users/5171a35d82074e068ce2

応答 (ユーザーが見つかりません。詳細は必要なく、状態のみです)。
{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:Error"
    ],
    "status": "404",
    "detail": "Resource 23B51B0E5D7AE9110A49411D@7cca31655d49f3640a494224 not found"
}

クエリによるユーザーの取得

Request

GET /Users?filter=userName eq "Test_User_dfeef4c5-5681-4387-b016-bdf221e82081"

Response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
    "totalResults": 1,
    "Resources": [{
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "id": "2441309d85324e7793ae",
        "externalId": "7fce0092-d52e-4f76-b727-3955bd72c939",
        "meta": {
            "resourceType": "User",
            "created": "2018-03-27T19:59:26.000Z",
            "lastModified": "2018-03-27T19:59:26.000Z"
            
        },
        "userName": "Test_User_dfeef4c5-5681-4387-b016-bdf221e82081",
        "name": {
            "familyName": "familyName",
            "givenName": "givenName"
        },
        "active": true,
        "emails": [{
            "value": "Test_User_91b67701-697b-46de-b864-bd0bbe4f99c1@testuser.com",
            "type": "work",
            "primary": true
        }]
    }],
    "startIndex": 1,
    "itemsPerPage": 20
}

クエリによるユーザーの取得 - 0 件の結果

Request

GET /Users?filter=userName eq "non-existent user"

Response

HTTP/1.1 200 OK

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

ユーザーの更新 [複数値のプロパティ]

Request

PATCH /Users/6764549bef60420686bc HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
            {
            "op": "Replace",
            "path": "emails[type eq \"work\"].value",
            "value": "updatedEmail@microsoft.com"
            },
            {
            "op": "Replace",
            "path": "name.familyName",
            "value": "updatedFamilyName"
            }
    ]
}
Response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "6764549bef60420686bc",
    "externalId": "6c75de36-30fa-4d2d-a196-6bdcdb6b6539",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "userName": "Test_User_fbb9dda4-fcde-4f98-a68b-6c5599e17c27",
    "name": {
        "formatted": "givenName updatedFamilyName",
        "familyName": "updatedFamilyName",
        "givenName": "givenName"
    },
    "active": true,
    "emails": [{
        "value": "updatedEmail@microsoft.com",
        "type": "work",
        "primary": true
    }]
}

ユーザーの更新 [単一値のプロパティ]

Request

PATCH /Users/5171a35d82074e068ce2 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Replace",
        "path": "userName",
        "value": "5b50642d-79fc-4410-9e90-4c077cdd1a59@testuser.com"
    }]
}
Response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": "5171a35d82074e068ce2",
    "externalId": "aa1eca08-7179-4eeb-a0be-a519f7e5cd1a",
    "meta": {
        "resourceType": "User",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
        
    },
    "userName": "5b50642d-79fc-4410-9e90-4c077cdd1a59@testuser.com",
    "name": {
        "formatted": "givenName familyName",
        "familyName": "familyName",
        "givenName": "givenName",
    },
    "active": true,
    "emails": [{
        "value": "Test_User_49dc1090-aada-4657-8434-4995c25a00f7@testuser.com",
        "type": "work",
        "primary": true
    }]
}

ユーザーの無効化

Request

PATCH /Users/5171a35d82074e068ce2 HTTP/1.1

{
    "Operations": [
        {
            "op": "Replace",
            "path": "active",
            "value": false
        }
    ],
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:PatchOp"
    ]
}
Response
{
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "id": "CEC50F275D83C4530A495FCF@834d0e1e5d8235f90a495fda",
    "userName": "deanruiz@testuser.com",
    "name": {
        "familyName": "Harris",
        "givenName": "Larry"
    },
    "active": false,
    "emails": [
        {
            "value": "gloversuzanne@testuser.com",
            "type": "work",
            "primary": true
        }
    ],
    "addresses": [
        {
            "country": "ML",
            "type": "work",
            "primary": true
        }
    ],
    "meta": {
        "resourceType": "Users",
        "location": "/scim/5171a35d82074e068ce2/Users/CEC50F265D83B4530B495FCF@5171a35d82074e068ce2"
    }
}

ユーザーの削除

Request

DELETE /Users/5171a35d82074e068ce2 HTTP/1.1

Response

HTTP/1.1 204 No Content

グループ操作

  • グループは、常に空のメンバーのリストで作成されます。
  • グループは displayName 属性でクエリすることができます。
  • グループ PATCH 要求を更新すると、応答に HTTP 204 No Content が含まれることになります。 全メンバーのリストを含めて本文を返すことはお勧めできません。
  • グループの全メンバーを返すことをサポートする必要はありません。

グループの作成

Request

POST /Groups HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group", "http://schemas.microsoft.com/2006/11/ResourceManagement/ADSCIM/2.0/Group"],
    "externalId": "8aa1a0c0-c4c3-4bc0-b4a5-2ef676900159",
    "displayName": "displayName",
    "meta": {
        "resourceType": "Group"
    }
}
Response

HTTP/1.1 201 Created

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": "927fa2c08dcb4a7fae9e",
    "externalId": "8aa1a0c0-c4c3-4bc0-b4a5-2ef676900159",
    "meta": {
        "resourceType": "Group",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
        
    },
    "displayName": "displayName",
    "members": []
}

グループの取得

Request

GET /Groups/40734ae655284ad3abcc?excludedAttributes=members HTTP/1.1

Response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": "40734ae655284ad3abcc",
    "externalId": "60f1bb27-2e1e-402d-bcc4-ec999564a194",
    "meta": {
        "resourceType": "Group",
        "created": "2018-03-27T19:59:26.000Z",
        "lastModified": "2018-03-27T19:59:26.000Z"
    },
    "displayName": "displayName",
}

displayName でのグループの取得

Request

GET /Groups?excludedAttributes=members&filter=displayName eq "displayName" HTTP/1.1

Response

HTTP/1.1 200 OK

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
    "totalResults": 1,
    "Resources": [{
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
        "id": "8c601452cc934a9ebef9",
        "externalId": "0db508eb-91e2-46e4-809c-30dcbda0c685",
        "meta": {
            "resourceType": "Group",
            "created": "2018-03-27T22:02:32.000Z",
            "lastModified": "2018-03-27T22:02:32.000Z",
            
        },
        "displayName": "displayName",
    }],
    "startIndex": 1,
    "itemsPerPage": 20
}

グループの更新 [非メンバー属性]

Request

PATCH /Groups/fa2ce26709934589afc5 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Replace",
        "path": "displayName",
        "value": "1879db59-3bdf-4490-ad68-ab880a269474updatedDisplayName"
    }]
}
Response

HTTP/1.1 204 No Content

グループの更新 [メンバーの追加]

Request

PATCH /Groups/a99962b9f99d4c4fac67 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Add",
        "path": "members",
        "value": [{
            "$ref": null,
            "value": "f648f8d5ea4e4cd38e9c"
        }]
    }]
}
Response

HTTP/1.1 204 No Content

グループの更新 [メンバーの削除]

Request

PATCH /Groups/a99962b9f99d4c4fac67 HTTP/1.1

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{
        "op": "Remove",
        "path": "members",
        "value": [{
            "$ref": null,
            "value": "f648f8d5ea4e4cd38e9c"
        }]
    }]
}
Response

HTTP/1.1 204 No Content

グループの削除

Request

DELETE /Groups/cdb1ce18f65944079d37 HTTP/1.1

Response

HTTP/1.1 204 No Content

スキーマ検出

スキーマの検出

Request

GET /Schemas

Response

HTTP/1.1 200 OK

{
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "itemsPerPage": 50,
    "startIndex": 1,
    "totalResults": 3,
    "Resources": [
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:core:2.0:User",
    "name" : "User",
    "description" : "User Account",
    "attributes" : [
      {
        "name" : "userName",
        "type" : "string",
        "multiValued" : false,
        "description" : "Unique identifier for the User, typically
used by the user to directly authenticate to the service provider.
Each User MUST include a non-empty userName value.  This identifier
MUST be unique across the service provider's entire set of Users.
REQUIRED.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "server"
      },                
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
        "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User"
    }
  },
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:core:2.0:Group",
    "name" : "Group",
    "description" : "Group",
    "attributes" : [
      {
        "name" : "displayName",
        "type" : "string",
        "multiValued" : false,
        "description" : "A human-readable name for the Group.
REQUIRED.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
        "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group"
    }
  },
  {
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
    "id" : "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
    "name" : "EnterpriseUser",
    "description" : "Enterprise User",
    "attributes" : [
      {
        "name" : "employeeNumber",
        "type" : "string",
        "multiValued" : false,
        "description" : "Numeric or alphanumeric identifier assigned
to a person, typically based on order of hire or association with an
organization.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
    ],
    "meta" : {
      "resourceType" : "Schema",
      "location" :
"/v2/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
    }
  }
]
}

セキュリティ要件

TLS プロトコルのバージョン

許容される TLS プロトコルのバージョンは、TLS 1.2 と TLS 1.3 だけです。 他のバージョンの TLS は許可されません。 SSL のバージョンは許可されません。

  • RSA キーは、2,048 ビット以上である必要があります。
  • ECC キーは 256 ビット以上で、承認された楕円曲線を使用して生成されている必要があります

キーの長さ

すべてのサービスでは、十分な長さの暗号化キーを使用して生成された X.509 証明書が使用されている必要があります。

暗号スイート

すべてのサービスは、以下の暗号スイートを、次に示す厳密な順序で使用するように、構成する必要があります。 RSA 証明書だけがある場合は、ECDSA 暗号スイートをインストールしても何の影響もありません。

TLS 1.2 暗号スイートの最低条件:

  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

IP 範囲

Azure AD プロビジョニング サービスは、現在、こちらに記載されている AzureActiveDirectory の IP 範囲で動作します。 AzureActiveDirectory タグの下に一覧表示されている IP 範囲を追加し、Azure AD プロビジョニング サービスからアプリケーションへのトラフィックを許可できます。 計算されたアドレスについて、IP 範囲の一覧を注意深く確認する必要があります。 '40.126.25.32' などのアドレスは、IP 範囲の一覧では '40.126.0.0/18' として表されることがあります。 次の API を使用して、プログラムによって IP 範囲の一覧を取得することもできます。

また、Microsoft Azure Active Directory は、プライベート ネットワーク (オンプレミス、Azure でホストされている、AWS でホストされているなど) 内のアプリケーションへの接続を提供するエージェント ベースのソリューションもサポートします。 お客様は、プライベート ネットワーク内のサーバーで、受信ポートを開くことなく Microsoft Azure Active Directory への接続を提供する軽量のエージェントをデプロイできます。 こちらをご覧ください。

SCIM エンドポイントを構築する

これでスキーマを設計し、Azure AD SCIM の実装を理解したので、SCIM エンドポイントの開発を開始できます。 最初から開始して完全に独自の実装を構築するのではなく、SCIM コミュニティによって発行された多数のオープンソース SCIM ライブラリを使用できます。

例を含め、SCIM エンドポイントを構築する方法に関するガイダンスについては、サンプル SCIM エンドポイントの開発に関する記事をご覧ください。

Azure AD プロビジョニング チームによって発行されたオープンソースの .NET Core 参照コード例は、開発をすぐに開始するためのリソースの 1 つです。 SCIM エンドポイントを構築したら、それをテストします。参照コードの一部として提供されている Postman テストのコレクションを使用したり、上記の要求または応答のサンプルを通じて実行したりすることができます。

注意

参照コードは、SCIM エンドポイントのビルドを開始するためのものであり、"現状のまま" 提供されます。コードのビルドと保守に役立つため、コミュニティからの貢献が歓迎されます。

このソリューションは、Microsoft.SCIM および Microsoft.SCIM.WebHostSample の 2 つのプロジェクトで構成されています。

Microsoft.SCIM プロジェクトは、SCIM 仕様に準拠する Web サービスのコンポーネントを定義するライブラリです。 これによりインターフェイス Microsoft.SCIM.IProvider が宣言され、要求がプロバイダーのメソッドへの呼び出しに変換され、ID ストアで動作するようにプログラムされます。

内訳:プロバイダーのメソッドへの呼び出しに変換された要求

Microsoft.SCIM.WebHostSample プロジェクトは、空のテンプレートに基づく ASP.NET Core Web アプリケーションです。 これにより、サンプル コードをスタンドアロンとしてデプロイし、コンテナーまたはインターネット インフォメーション サービス内でホストすることができます。 また、Microsoft.SCIM.IProvider インターフェイスを実装して、クラスをサンプル ID ストアとしてメモリに保持することができます。

public class Startup
{
    ...
    public IMonitor MonitoringBehavior { get; set; }
    public IProvider ProviderBehavior { get; set; }

    public Startup(IWebHostEnvironment env, IConfiguration configuration)
    {
        ...
        this.MonitoringBehavior = new ConsoleMonitor();
        this.ProviderBehavior = new InMemoryProvider();
    }
    ...

カスタム SCIM エンドポイントの構築

SCIM エンドポイントには、HTTP アドレスと、ルート証明機関が次のいずれかの名前であるサーバー認証証明書が設定されている必要があります。

  • CNNIC
  • Comodo
  • CyberTrust
  • DigiCert
  • GeoTrust
  • GlobalSign
  • Go Daddy
  • VeriSign
  • WoSign
  • DST Root CA X3

.NET Core SDK には、開発時に使用できる HTTPS 開発証明書が含まれています。この証明書は、最初の実行エクスペリエンスの一部としてインストールされます。 ASP.NET Core Web アプリケーションの実行方法に応じて、異なるポートがリッスンされます。

  • Microsoft.SCIM.WebHostSample: https://localhost:5001
  • IIS Express: https://localhost:44359

ASP.NET Core の HTTPS の詳細については、次のリンクを参照してください: 「ASP.NET Core に HTTPS を適用する

エンドポイント認証の処理

Azure AD プロビジョニング サービスからの要求には、OAuth 2.0 のベアラー トークンが含まれます。 ベアラー トークンは、Azure AD などの承認サーバーによって発行され、アプリケーションによって信頼されるセキュリティ トークンです。 次のいずれかのトークンを使用するように Azure AD プロビジョニング サービスを構成できます。

  • 有効期間が長いベアラー トークン SCIM エンドポイントで、Azure AD 以外の発行者からの OAuth ベアラー トークンを必要とする場合は、必要な OAuth ベアラー トークンをオプションの [シークレット トークン] フィールドにコピーします。 開発環境では、/scim/token エンドポイントからのテスト トークンを使用できます。 運用環境ではテスト トークンを使用しないでください。

  • Azure AD ベアラー トークン。 [シークレット トークン] フィールドを空白のままにすると、Azure AD は各要求に Azure AD を発行元とする OAuth ベアラー トークンを含めます。 ID プロバイダーとして Azure AD を使用するアプリは、この Azure AD によって発行されたトークンを検証できます。

    • 要求を受け取るアプリケーションは、トークンの発行元が想定される Azure AD テナントとしての Azure AD であることを検証する必要があります。
    • トークンでは、発行者は、iss 要求によって識別されます。 たとえば、「 "iss":"https://sts.windows.net/12345678-0000-0000-0000-000000000000/" 」のように入力します。 この例では、要求値のベース アドレスである https://sts.windows.net が、発行者として Azure AD を識別します。一方で、相対アドレス セグメントである 12345678-0000-0000-0000-000000000000 は、トークンの発行対象となった Azure AD テナントの一意識別子になっています。
    • トークンの対象は、ギャラリー内のアプリケーションのアプリケーション ID です。 単一のテナントに登録されているアプリケーションは、同じ iss 要求を SCIM 要求と共に受信します。 すべてのカスタム アプリのアプリケーション ID は 8adf8e6e-67b2-4cf2-a259-e3dc5476c621 です。 Azure AD プロビジョニング サービスによって生成されたトークンは、テストにのみ使用する必要があります。 運用環境では使用しないでください。

このサンプル コードでは、要求は Microsoft.AspNetCore.Authentication.JwtBearer パッケージを使用して認証されます。 次のコードでは、あらゆるサービスのエンドポイントに対する要求が、指定のテナントに対して Azure AD から発行されたベアラー トークンを使用して認証されるようになります。

public void ConfigureServices(IServiceCollection services)
{
    if (_env.IsDevelopment())
    {
        ...
    }
    else
    {
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
            .AddJwtBearer(options =>
            {
                options.Authority = " https://sts.windows.net/12345678-0000-0000-0000-000000000000/";
                options.Audience = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621";
                ...
            });
    }
    ...
}

public void Configure(IApplicationBuilder app)
{
    ...
    app.UseAuthentication();
    app.UseAuthorization();
    ...
}

ベアラートークンは、提供された Postman テストを使用し、localhost を使用してローカル デバッグを実行するためにも必要です。 このサンプル コードでは、ASP.NET Core 環境を使用し、開発段階で認証オプションを変更して、自己署名トークンを使用できるようにします。

ASP.NET Core の複数の環境について詳しくは、「ASP.NET Core で複数の環境を使用する」を参照してください。

次のコードでは、あらゆるサービスのエンドポイントに対する要求が、カスタム キーを使用して署名されたベアラー トークンを使用して認証されるようになります。

public void ConfigureServices(IServiceCollection services)
{
    if (_env.IsDevelopment())
    {
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters =
                new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = false,
                    ValidIssuer = "Microsoft.Security.Bearer",
                    ValidAudience = "Microsoft.Security.Bearer",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("A1B2C3D4E5F6A1B2C3D4E5F6"))
                };
        });
    }
...

GET 要求をトークン コントローラーに送信することで有効なベアラー トークンが取得されます。メソッド GenerateJSONWebToken により、開発用に構成されたパラメーターに一致するトークンが作成されます。

private string GenerateJSONWebToken()
{
    // Create token key
    SymmetricSecurityKey securityKey =
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes("A1B2C3D4E5F6A1B2C3D4E5F6"));
    SigningCredentials credentials =
        new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    // Set token expiration
    DateTime startTime = DateTime.UtcNow;
    DateTime expiryTime = startTime.AddMinutes(120);

    // Generate the token
    JwtSecurityToken token =
        new JwtSecurityToken(
            "Microsoft.Security.Bearer",
            "Microsoft.Security.Bearer",
            null,
            notBefore: startTime,
            expires: expiryTime,
            signingCredentials: credentials);

    string result = new JwtSecurityTokenHandler().WriteToken(token);
    return result;
}

ユーザーのプロビジョニングとプロビジョニング解除の処理

例 1.一致するユーザーをサービスに照会する

Azure AD は、Azure AD 内のユーザーの mailNickname 属性値に一致する externalId 属性値を持つユーザーをサービスに照会します。 クエリは次の例のようなハイパーテキスト転送プロトコル (HTTP) 要求として表現されます。jyoung は Azure AD 内のユーザーの mailNickname 例です。

注意

これは一例です。 すべてのユーザーに mailNickname 属性があるわけではありません。また、ユーザーが持つ値はディレクトリ内で一意ではない場合もあります。 また、照合に使用される属性 (この場合は externalId) は、Azure AD 属性マッピングで構成可能です。

GET https://.../scim/Users?filter=externalId eq jyoung HTTP/1.1
 Authorization: Bearer ...

このサンプル コードでは、要求はサービスのプロバイダーの QueryAsync メソッドへの呼び出しに変換されます。 このメソッドのシグネチャを次に示します。

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource is defined in 
// Microsoft.SCIM.Schemas.  
// Microsoft.SCIM.IQueryParameters is defined in 
// Microsoft.SCIM.Protocol.  

Task<Resource[]> QueryAsync(IRequest<IQueryParameters> request);

externalId 属性に特定の値を持つユーザーのサンプル クエリでは、QueryAsync メソッドに渡される引数の値は次のようになります。

  • parameters.AlternateFilters.Count:1
  • parameters.AlternateFilters.ElementAt(0).AttributePath: "externalId"
  • parameters.AlternateFilters.ElementAt(0).ComparisonOperator:ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(0).ComparisonValue: "jyoung"

例 2.ユーザーをプロビジョニングする

ユーザーの mailNickname 属性値に一致する externalId 属性値を持つユーザーを SCIM エンドポイントに照会したときに、応答でユーザーが返されなかった場合、Azure AD は、Azure AD 内のユーザーに対応するユーザーをプロビジョニングするようにサービスに要求します。 このような要求の例を次に示します。

POST https://.../scim/Users HTTP/1.1
Authorization: Bearer ...
Content-type: application/scim+json
{
   "schemas":
   [
     "urn:ietf:params:scim:schemas:core:2.0:User",
     "urn:ietf:params:scim:schemas:extension:enterprise:2.0User"],
   "externalId":"jyoung",
   "userName":"jyoung@testuser.com",
   "active":true,
   "addresses":null,
   "displayName":"Joy Young",
   "emails": [
     {
       "type":"work",
       "value":"jyoung@Contoso.com",
       "primary":true}],
   "meta": {
     "resourceType":"User"},
    "name":{
     "familyName":"Young",
     "givenName":"Joy"},
   "phoneNumbers":null,
   "preferredLanguage":null,
   "title":null,
   "department":null,
   "manager":null}

このサンプル コードでは、要求はサービスのプロバイダーの CreateAsync メソッドへの呼び出しに変換されます。 このメソッドのシグネチャを次に示します。

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource is defined in 
// Microsoft.SCIM.Schemas.  

Task<Resource> CreateAsync(IRequest<Resource> request);

ユーザー プロビジョニングの要求では、resource 引数の値は、Microsoft.SCIM.Schemas ライブラリで定義されている Microsoft.SCIM.Core2EnterpriseUser クラスのインスタンスです。 ユーザーをプロビジョニングする要求が成功すると、メソッドの実装により、Microsoft.SCIM.Core2EnterpriseUser クラスのインスタンスが返され、Identifier プロパティの値に新たにプロビジョニングされたユーザーの一意識別子が設定されると想定されています。

例 3.ユーザーの現在の状態を照会する

SCIM によってアクセスされる ID ストアに存在することがわかっているユーザーを更新するために、Azure AD は、次のような要求を使用して、そのユーザーの現在の状態をサービスに要求して処理を続行します。

GET ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...

このサンプル コードでは、要求はサービスのプロバイダーの RetrieveAsync メソッドへの呼び出しに変換されます。 このメソッドのシグネチャを次に示します。

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.Resource and 
// Microsoft.SCIM.IResourceRetrievalParameters 
// are defined in Microsoft.SCIM.Schemas 

Task<Resource> RetrieveAsync(IRequest<IResourceRetrievalParameters> request);

ユーザーの現在の状態を取得する要求の例では、parameters 引数の値として指定されたオブジェクトのプロパティ値は次のようになります。

  • Identifier:"54D382A4-2050-4C03-94D1-E769F1D15682"
  • SchemaIdentifier: urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

例 4.更新する参照属性の値を照会する

参照属性を更新する場合、Azure AD は、サービスによってアクセスされる ID ストア内の参照属性の現在の値が Azure AD 内のその属性の値と既に一致しているかどうかを判別するために、サービスにクエリを実行します。 ユーザーの場合、この方法で現在の値を照会する属性は、manager 属性のみです。 ユーザー オブジェクトの manager 属性に特定の値があるかどうかを判別する要求の例を次に示します。このサンプル コードでは、要求はサービスのプロバイダーの QueryAsync メソッドへの呼び出しに変換されます。 parameters 引数の値として指定されたオブジェクトのプロパティ値は次のようになります。

  • parameters.AlternateFilters.Count:2
  • parameters.AlternateFilters.ElementAt(x).AttributePath:"ID"
  • parameters.AlternateFilters.ElementAt(x).ComparisonOperator:ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(x).ComparisonValue:"54D382A4-2050-4C03-94D1-E769F1D15682"
  • parameters.AlternateFilters.ElementAt(y).AttributePath: "manager"
  • parameters.AlternateFilters.ElementAt(y).ComparisonOperator:ComparisonOperator.Equals
  • parameters.AlternateFilter.ElementAt(y).ComparisonValue:"2819c223-7f76-453a-919d-413861904646"
  • parameters.RequestedAttributePaths.ElementAt(0):"ID"
  • parameters.SchemaIdentifier: urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

インデックス x の値として 0 を指定し、インデックス y の値として 1 を指定することができます。 または、x の値をとして 1 を指定し、y の値として 0 を指定することもできます。 これはフィルター クエリ パラメーターの式の順序によって異なります。

例 5. Azure AD から SCIM エンドポイントに対するユーザーの更新を要求する

次に Azure AD から SCIM エンドポイントにユーザーの更新を要求する例を示します。

PATCH ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...
Content-type: application/scim+json
{
    "schemas": 
    [
      "urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations":
    [
      {
        "op":"Add",
        "path":"manager",
        "value":
          [
            {
              "$ref":"http://.../scim/Users/2819c223-7f76-453a-919d-413861904646",
              "value":"2819c223-7f76-453a-919d-413861904646"}]}]}

このサンプル コードでは、要求はサービスのプロバイダーの UpdateAsync メソッドへの呼び出しに変換されます。 このメソッドのシグネチャを次に示します。

// System.Threading.Tasks.Tasks and 
// System.Collections.Generic.IReadOnlyCollection<T>  // are defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in
// Microsoft.SCIM.Service.
// Microsoft.SCIM.IPatch, 
// is defined in Microsoft.SCIM.Protocol. 

Task UpdateAsync(IRequest<IPatch> request);

ユーザーを更新する要求の例では、patch 引数の値として指定されたオブジェクトのプロパティ値は次のようになります。

引数
ResourceIdentifier.Identifier "54D382A4-2050-4C03-94D1-E769F1D15682"
ResourceIdentifier.SchemaIdentifier urn:ietf:params:scim:schemas:extension:enterprise:2.0:User
(PatchRequest as PatchRequest2).Operations.Count 1
(PatchRequest as PatchRequest2).Operations.ElementAt(0).OperationName OperationName.Add
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Path.AttributePath Manager
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.Count 1
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.ElementAt(0).Reference http://.../scim/Users/2819c223-7f76-453a-919d-413861904646
(PatchRequest as PatchRequest2).Operations.ElementAt(0).Value.ElementAt(0).Value 2819c223-7f76-453a-919d-413861904646

例 6.ユーザーのプロビジョニングを解除する

SCIM エンドポイントによってアクセスされる ID ストアからユーザーのプロビジョニングを解除するために、Azure AD は次のような要求を送信します。

DELETE ~/scim/Users/54D382A4-2050-4C03-94D1-E769F1D15682 HTTP/1.1
Authorization: Bearer ...

このサンプル コードでは、要求はサービスのプロバイダーの DeleteAsync メソッドへの呼び出しに変換されます。 このメソッドのシグネチャを次に示します。

// System.Threading.Tasks.Tasks is defined in mscorlib.dll.  
// Microsoft.SCIM.IRequest is defined in 
// Microsoft.SCIM.Service.  
// Microsoft.SCIM.IResourceIdentifier, 
// is defined in Microsoft.SCIM.Protocol. 

Task DeleteAsync(IRequest<IResourceIdentifier> request);

ユーザーのプロビジョニングを解除する要求の例では、resourceIdentifier 引数の値として指定されたオブジェクトのプロパティ値は次のようになります。

  • ResourceIdentifier.Identifier:"54D382A4-2050-4C03-94D1-E769F1D15682"
  • ResourceIdentifier.SchemaIdentifier: urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

SCIM エンドポイントを Azure AD プロビジョニング サービスと統合します。

Azure AD は、割り当てられたユーザーとグループを、SCIM 2.0 プロトコルの特定のプロファイルを実装したアプリケーションに自動的にプロビジョニングするように構成できます。 プロファイルの仕様は、Azure AD SCIM の実装についてのセクションに記載されています。

これらの要件との互換性に関する記述については、アプリケーション プロバイダー、またはアプリケーション プロバイダーのドキュメントを確認してください。

重要

Azure AD SCIM 実装は、Azure AD とターゲット アプリケーション間でユーザーを常に同期するように設計された Azure AD ユーザー プロビジョニング サービスの上に構築され、固有の標準操作セットを実装しています。 Azure AD プロビジョニング サービスの動作を理解するには、これらの動作を把握しておくことが重要です。 詳しくは、「プロビジョニング サイクル: 初回と増分」を参照してください。これは「プロビジョニングのしくみ」に含まれるセクションです。

作業の開始

この記事で説明した SCIM プロファイルをサポートするアプリケーションは、Azure AD アプリケーション ギャラリーの "ギャラリー以外のアプリケーション" 機能を使用して Azure AD に接続できます。 接続が完了すると、Azure AD は 40 分ごとに同期処理を実行します。この処理では、割り当て済みのユーザーとグループについてアプリケーションの SCIM エンドポイントに照会し、割り当ての詳細に従ってユーザーとグループを作成または変更します。

SCIM をサポートするアプリケーションを接続するには:

  1. Azure AD ポータルにサインインします。 開発者プログラムにサインアップすることにより、P2 ライセンスで Azure AD の無料試用版にアクセスできます。

  2. 左側のウィンドウで、 [エンタープライズ アプリケーション] を選択します。 ギャラリーから追加されたアプリを含む、構成済みのすべてのアプリの一覧が表示されます。

  3. [+ 新しいアプリケーション]>[+ 独自のアプリケーションの作成] の順に選択します。

  4. アプリケーションの名前を入力し、 [ギャラリーに見つからないその他のアプリケーションを統合します] オプションを選択します。 [追加] を選択して、アプリ オブジェクトを作成します。 新しいアプリがエンタープライズ アプリケーションの一覧に追加され、そのアプリの管理画面が開きます。

    次のスクリーンショットは、Azure AD アプリケーション ギャラリーを示しています。

    Azure AD アプリケーション ギャラリーを示すスクリーンショット。

    注意

    古いアプリ ギャラリー エクスペリエンスを使用している場合は、次の画面ガイドに従ってください。

    次のスクリーンショットは、Azure AD の古いアプリ ギャラリー エクスペリエンスを示しています。

    Azure AD の古いアプリ ギャラリー エクスペリエンスを示すスクリーンショット。

  5. アプリの管理画面で、左側のパネルにある [プロビジョニング] を選択します。

  6. [プロビジョニング モード] メニューの [自動] を選択します。

    次のスクリーンショットは、Azure Portal におけるプロビジョニング設定の構成を示しています。

    Azure portal のアプリ プロビジョニング ページのスクリーンショット。

  7. [テナント URL] フィールドに、アプリケーションの SCIM エンドポイントの URL を入力します。 例: https://api.contoso.com/scim/

  8. SCIM エンドポイントで、Azure AD 以外の発行者からの OAuth ベアラー トークンを必要とする場合は、必要な OAuth ベアラー トークンをオプションの [シークレット トークン] フィールドにコピーします。 このフィールドを空白のままにすると、Azure AD では各要求に Azure AD を発行元とする OAuth ベアラー トークンを含めます。 ID プロバイダーとして Azure AD を使用するアプリは、この Azure AD によって発行されたトークンを検証できます。

    注意

    このフィールドを空白のままにして、Azure AD によって生成されるトークンに依存することは推奨 "されません"。 このオプションは、主にテスト目的で使用できます。

  9. [テスト接続] を選択して、Azure AD の SCIM エンドポイントへの接続を試みます。 試行に失敗した場合は、エラー情報が表示されます。

    注意

    テスト接続では、Azure AD 構成で照合プロパティとして選択されたランダムな GUID を使用して、存在しないユーザー用の SCIM エンドポイントのクエリが実行されます。 想定される適切な応答は、HTTP 200 OK と空の SCIM ListResponse メッセージです。

  10. アプリケーションへの接続の試行に成功した場合は、 [保存] を選択して管理者資格情報を保存します。

  11. [マッピング] セクションには、選択可能な 2 つの属性マッピングのセットがあります。片方はユーザー オブジェクト用であり、他方はグループ オブジェクト用です。 Azure AD からアプリに同期されている属性を確認するには、それぞれを選択します。 [Matching](照合) プロパティとして選択されている属性は、更新処理でアプリ内のユーザーとアカウントを照合するために使用されます。 すべての変更をコミットするには、 [保存] を選択します。

    注意

    必要に応じて [グループ] マッピングを無効にすることで、グループ オブジェクトの同期を無効にできます。

  12. [設定][スコープ] フィールドは、どのユーザーおよびグループが同期されるかを定義します。 [割り当てられたユーザーとグループのみを同期する] (推奨) を選択すると、 [ユーザーとグループ] タブに割り当てられたユーザーとグループのみが同期されます。

  13. 構成が完了したら、 [プロビジョニング状態][オン] に設定します。

  14. Azure AD のプロビジョニング サービスを開始するには、 [保存] を選択します。

  15. 割り当てられたユーザーとグループのみを同期する (推奨) 場合は、[ユーザーとグループ] タブを選択し、同期するユーザーとグループを割り当てます。

初期サイクルが開始されたら、左側のパネルにある [プロビジョニング ログ] を選択して進行状況を監視できます。これにより、プロビジョニング サービスによって実行されたすべてのアクションがアプリで表示されます。 Azure AD プロビジョニング ログの読み取りの詳細については、「自動ユーザー アカウント プロビジョニングについてのレポート」をご覧ください。

注意

初期サイクルは、サービスが実行されている限り約 40 分ごとに実行される以降の同期よりも、実行に時間がかかります。

複数のテナントによって使用されるアプリケーションを作成する場合は、Azure AD アプリケーション ギャラリーで使用可能にできます。 組織で簡単にアプリケーションを見つけて、プロビジョニングを構成することができます。 簡単に、Azure AD ギャラリーにアプリを発行し、他のユーザーがプロビジョニングできるようにすることができます。 手順は、 こちらで確認してください。 Microsoft はお客様と協力して、お客様のアプリケーションをギャラリーに統合し、エンドポイントをテストし、顧客が使用できるオンボード ドキュメントをリリースします。

アプリケーションを迅速にオンボードし、スムーズなデプロイ エクスペリエンスを顧客に提供するために、チェックリストを使用します。 ギャラリーにオンボードする際に、ご自身から情報が収集されます。

  • SCIM 2.0 のユーザーおよびグループ エンドポイントをサポートする (必要なのは 1 つだけですが両方を推奨)
  • ユーザーとグループが遅延なく確実にプロビジョニングされ、プロビジョニング解除されるよう、テナントあたり、少なくとも毎秒 25 件の要求をサポートする (必須)
  • 顧客のギャラリー オンボード後のガイドを行うエンジニアリングとサポートの連絡先を確立する (必須)
  • アプリケーションの 3 つの無期限のテスト資格情報 (必須)
  • 次に示すように、OAuth 承認コードの付与または有効期間が長いトークンをサポートする (必須)
  • 顧客のギャラリー オンボード後のサポートを行うエンジニアリングとサポートの連絡先を確立する (必須)
  • スキーマ検出をサポートする (必須)
  • 1 つの PATCH で複数のグループ メンバーシップの更新をサポートする
  • SCIM エンドポイントを公開文書化する

SCIM 仕様では、SCIM 固有の認証と認可のスキームは定義されておらず、既存の業界標準の使用に依存しています。

承認方法 長所 短所 サポート
ユーザー名とパスワード (推奨されないか、Azure AD でサポートされていません) 簡単に実装できます セキュリティで保護されていません - 「パスワードは重要ではない」を参照 新しいギャラリー アプリまたはギャラリー外のアプリではサポートされません。
有効期間が長いベアラー トークン 有効期間が長いトークンでは、ユーザーが存在している必要はありません。 プロビジョニングを設定する場合、管理者はこれらを簡単に使用できます。 有効期間が長いトークンは、メールのようにセキュリティで保護されていない方法を使用しないと、管理者と共有するのが困難です。 ギャラリー アプリとギャラリー以外のアプリでサポートされます。
OAuth 認証コードの付与 アクセス トークンの有効期間はパスワードよりもはるかに短く、有効期間が長いベアラー トークンにはない自動更新メカニズムがあります。 初期承認中に実際のユーザーが存在する必要があり、アカウンタビリティのレベルを追加します。 ユーザーが存在している必要があります。 ユーザーが組織からいなくなる場合、トークンは無効になり、承認を再度完了する必要があります。 ギャラリー アプリでサポートされていますが、ギャラリー以外のアプリではサポートされていません。 ただし、短期的なテストのために、UI のアクセス トークンをシークレット トークンとして提供することができます。 ギャラリー アプリに対する構成可能な認証 URL またはトークン URL のサポートに加え、ギャラリー以外での OAuth コードの付与に対するサポートもバックログに入っています。
OAuth クライアント資格情報の付与 アクセス トークンの有効期間はパスワードよりもはるかに短く、有効期間が長いベアラー トークンにはない自動更新メカニズムがあります。 承認コードの付与とクライアント資格情報の付与の両方で、同じ種類のアクセス トークンが作成されるため、これらの方法間の移動は API に対して透過的です。 プロビジョニングは自動化することができ、ユーザーの介入なしに新しいトークンを自動的に要求することができます。 ギャラリー アプリでサポートされていますが、ギャラリー以外のアプリではサポートされていません。 ただし、短期的なテストのために、UI のアクセス トークンをシークレット トークンとして提供することができます。 ギャラリー以外での OAuth クライアント資格情報の付与に対するサポートはバックログに入っています。

注意

Azure AD プロビジョニング構成のカスタム アプリ UI では、トークン フィールドを空白のままにすることはお勧めしません。 生成されたトークンは、主にテスト目的で使用できます。

OAuth コード付与フロー

プロビジョニング サービスでは、認可コードの付与がサポートされています。ギャラリーにアプリを発行するための要求を送信した後、私たちのチームは次の情報を収集するためにお客様と協力します。

  • 認可 URL: ユーザー エージェント リダイレクトによってリソース所有者から承認を取得するためのクライアントによる URL。 ユーザーは、アクセスを承認するためにこの URL にリダイレクトされます。

  • トークン交換 URL: アクセス トークンの認可付与を交換するためのクライアントによる URL。通常は、クライアント認証を使用します。

  • クライアント ID: 認可サーバーは、登録されたクライアントにクライアント識別子 (クライアントによって提供される登録情報を表す一意の文字列) を発行します。 クライアント識別子はシークレットではありません。これはリソースの所有者に公開されており、クライアント認証に単独で使用できません

  • クライアント シークレット: 認可サーバーによって生成されるシークレット。これは認可サーバーにのみ認識される一意の値である必要があります。

Note

現在、認可 URLトークン交換 URL をテナントごとに構成することはできません。

Note

OAuth v1 は、クライアント シークレットの露出が原因でサポートされていません。 OAuth v2 はサポートされています。

ベスト プラクティス (推奨されますが必須ではありません):

  • 複数のリダイレクト URL をサポートします。 管理者は、"portal.azure.com" と "aad.portal.azure.com" の両方からプロビジョニングを構成できます。 複数のリダイレクト URL をサポートすることで、ユーザーがいずれのポータルからでもアクセスを承認できるようになります。
  • 複数のシークレットをサポートして、ダウンタイムなしで容易に更新できるようにします。

OAuth コード付与フローをセットアップする方法

  1. Azure portal にサインインし、 [エンタープライズ アプリケーション]>[アプリケーション]>[プロビジョニング] に移動し、 [承認] を選択します。

    1. ユーザーは Azure portal によって、承認 URL (サード パーティのアプリのサインイン ページ) にリダイレクトされます。

    2. 管理者は、サード パーティのアプリケーションに資格情報を提供します。

    3. サード パーティのアプリによってユーザーが Azure portal にリダイレクトし戻され、付与コードが提供されます。

    4. Azure AD プロビジョニング サービスによって、トークン URL が呼び出され、付与コードが提供されます。 サード パーティのアプリケーションから、アクセス トークン、更新トークン、有効期限が含まれた応答が返されます。

  2. プロビジョニング サイクルが開始されると、サービスによって現在のアクセス トークンが有効かどうかが確認され、必要に応じて新しいトークンと交換されます。 アクセス トークンは、アプリに対して行われた各要求で提供され、要求の有効性は各要求の前に確認されます。

Note

ギャラリー以外のアプリケーションで OAuth を設定することはできませんが、認可サーバーからアクセス トークンを手動で生成し、ギャラリー以外のアプリケーションにシークレット トークンとして入力することができます。 これにより、OAuth コード付与がサポートされるアプリ ギャラリーにオンボードする前に、SCIM サーバーと Azure AD プロビジョニング サービスとの互換性を確認できます。

有効期間が長い OAuth ベアラー トークン: アプリケーションで OAuth 認可コード付与フローがサポートされていない場合は、管理者がプロビジョニング統合のセットアップに使用できる、有効期間が長い OAuth ベアラー トークンを生成してください。 トークンは永続的である必要があり、そうでない場合、トークンの有効期限が切れるとプロビジョニング ジョブが検疫されます。

追加の認証および承認方法については、UserVoice にご連絡ください。

共同統合の認識と需要を促進するために、既存のドキュメントを更新し、お使いのマーケティング チャネルにおける統合を拡充することをお勧めします。 Launch をサポートするために、次のチェックリストを完了することをお勧めします。

  • 販売チームとカスタマー サポート チームが統合の機能を認識し、準備し、それについて説明できるようにします。 チームに概要を伝え、FAQ を提供し、統合を販売資料に含めます。
  • 共同統合、利点、および開始方法について説明するブログ投稿やプレス リリースを作成します。 例: Imprivata と Azure AD のプレス リリース
  • Twitter、Facebook、LinkedIn などのソーシャル メディアを活用して、顧客に統合を宣伝します。 投稿をリツイートできるように、必ず @AzureAD を含めるようにしてください。 例:Imprivata の Twitter 投稿
  • 共同統合が利用できるようになったことを含めるように、マーケティングのページや Web サイト (統合のページ、パートナーのページ、価格のページなど) を作成または更新します。 例:Pingboard の統合のページSmartsheet の統合のページMonday.com の価格ページ
  • 顧客がどのように開始できるかに関するヘルプ センターの記事またはテクニカル ドキュメントを作成します。 例: Envoy と Microsoft Azure AD の統合。
  • 顧客とのコミュニケーション (月次のニュースレター、メールによるキャンペーン、製品のリリース ノート) を通じて、新しい統合を顧客に通知します。

次のステップ