注意 : Azure Active Directory Graph は今後サポートされません。代わりに Microsoft Graph を使用してください。(同等の Azure AD 管理用の API が提供されています。)
開発者にとっての Azure Active Directory (Microsoft Entra ID)
- Azure Active Directory とは (事前準備)
- Web SSO 開発 – .NET 編 (WS-Fed)
- Web SSO 開発 – PHP, Node.js 編 (SAML) ※英語
- SaaS 連携 : Google Apps (SAML)
- SaaS 連携 : kintone (SAML)
- OpenID Connect サポート (OpenID)
- OAuth による Client の開発 (OAuth)
- OAuth による Service の開発 (OAuth)
- Common Consent Framework – Client 側 (OAuth)
- Common Consent Framework – Service 側 (OAuth)
- Application Role の使用 (OAuth)
- Backend Server-Side アプリの開発 (OAuth)
- Federated Credentials (OAuth) ※英語
- Login UI が表示できない場合のフロー (OAuth)
- JavaScript Application の開発 (OAuth)
- Windows 10 との SSO 開発 (Web Account Manager API)
- Active Directory (企業内 Windows 環境) との Federation と同期
- Multi-Factor Authentication
- Graph API
こんにちは。
Azure Active Directory Graph (Graph API) を使うと、REST の呼び出しで、ユーザーの作成・変更をおこなうような管理機能を提供したり、アプリケーション上でユーザー一覧 (ユーザー選択画面など) を提供したり、後述のようにバックエンドでユーザー情報を同期することなども可能です。(特に同期ソリューションは、Azure AD とカスタム アプリ (SaaS) を Federation させる上で重要な機能です。)
今回は、この Graph API について、その利用手順と概念を解説します。
2015/11 追記 : 本投稿で紹介する Azure AD Graph API も含め、Microsoft が提供するすべてのサービス / データの API が Microsoft Graph API に統一されました。(詳細は「Active Directory Team Blog : Introducing the Microsoft Graph –The Azure AD GraphAPI goes big time!」をご参照ください。)
今後は、 Microsoft Graph で下記と同様の開発 (プログラミング) が可能です。
認証処理と Access Token の取得
Graph API (Url は https://graph.windows.net/<tenant realm>) は後述で見ていくように REST で提供されていますが、この API 自身も Azure AD 上の Service Application (Web API) として、OAuth 2 による Access Token を取得してアクセスします。
これまで述べてきたように Access Token の取得方法はいくつかあります。(以下のいずれかの方法で取得できます。)
- 「Azure AD を使った API (Service) 連携の Client 開発」で紹介したフローを使って、ログイン画面を表示して Access Token を取得できます。(ログイン画面を使って、ユーザーにログインさせます。)
ここで述べるような Azure AD テナントの情報の読み込み・書き込みをおこなうには、「Azure Active Directory の Common Consent Framework」で記載している方法で、作成する Application (Client) の Permission (アクセス許可) として [Read and write directory data] を設定します。(この場合、必ず、管理者のアカウントでログインする必要があります。) - その他の方法として、「Azure AD : Backend Server-Side アプリの開発 (Deamon, Service など)」で解説した方法で Application Permissions を使って Access Token を取得できます。この場合、特定ユーザーではログインしないので、ログイン画面は表示されません。(この方法は、バックエンドの同期アプリなどで使えます。)
補足 : もし、People Picker のような一般ユーザーが使う機能を実装するときには、[Read all users’ basic profile] などの新しく追加された Delegated Permission を使用してください。この場合、管理者によるログインは不要です。(「New graph API consent permissions」を参照してください。)
ここでは、Azure AD の管理を目的とした使用方法を紹介するので、管理者権限が必要です。
なお、.NET (C# など)、Cordova、Objective-C、Android SDK などを使用されている方は、Active Directory Authentication Library (ADAL) を使用して Access Token を取得しても構いません。
. . .using Microsoft.IdentityModel.Clients.ActiveDirectory;. . .private void button1_Click(object sender, EventArgs e){ // // Get access token using login UI // AuthenticationContext context =new AuthenticationContext("https://login.microsoftonline.com/o365demo01.onmicrosoft.com"); AuthenticationResult assertion = context.AcquireToken("https://graph.windows.net", // resource (graph api)"39ff4d28-9cba-448c-acae-612705e54257", // client idnew Uri("https://localhost/sampleapp")); string authHeader = assertion.CreateAuthorizationHeader();}. . .
補足 : Azure Team Blog で紹介しているように、.NET 版の Active Directory Authentication Library (ADAL) の version 0.6 以降では、Full Managed (100% .NET) になりました。
0.6 以前では、 環境の相違 (x86, x64) に注意してください。
Graph API の呼び出し
つぎに、上記で取得した Access Token を使って、Graph API の REST サービスからデータを取得します。
例えば、下記の HTTP Request は o365demo01.onmicrosoft.com の Directory の User 一覧を取得します。
api-version の指定は必ず必要です。(現在サポートされている api-version については「MSDN : Azure AD Graph API Versioning」を参考にしてください。)
GET https://graph.windows.net/o365demo01.onmicrosoft.com/usersAuthorization: Bearer {access token}api-version: 1.0
結果 (HTTP Response) は以下の通りです。
HTTP/1.1 200 OKContent-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8Access-Control-Allow-Origin: *{ "odata.metadata": "https://graph.windows.net/o365demo01.onmicrosoft.com/$metadata#directoryObjects/Microsoft.WindowsAzure.ActiveDirectory.User", "value": [{ "odata.type": "Microsoft.WindowsAzure.ActiveDirectory.User", "objectType": "User", "objectId": "ca3645ea-e265-42c0-b1ff-bfb467c0352e", "accountEnabled": true, "assignedLicenses": [{ "disabledPlans": [ ], "skuId": "3b555118-da6a-4418-894f-7df1e2096870"} ], "assignedPlans": [{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Enabled", "service": "SharePoint", "servicePlanId": "c7699d2e-19aa-44de-8edf-1736da088ca1"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Enabled", "service": "exchange", "servicePlanId": "9aaf7827-d63c-4b61-89c3-182f06f82e5c"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Deleted", "service": "RMSOnline", "servicePlanId": "bea4c11e-220a-4e6d-8eb8-8ea15d019f90"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Deleted", "service": "MicrosoftOffice", "servicePlanId": "43de0ff5-c92c-492b-9116-175376d08c38"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Enabled", "service": "MicrosoftCommunicationsOnline", "servicePlanId": "0feaeb32-d00e-4d66-bd5a-43b5b83db82c"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Enabled", "service": "SharePoint", "servicePlanId": "e95bec33-7c88-4a70-8e19-b10bd9d0c014"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Deleted", "service": "SharePoint", "servicePlanId": "5dbe027f-2339-4123-9542-606e4d348a72"},{ "assignedTimestamp": "2015-04-06T09:50:28Z", "capabilityStatus": "Deleted", "service": "exchange", "servicePlanId": "efb87545-963c-4e0d-99df-69c6916d9eb0"} ], "city": null, "country": null, "department": null, "dirSyncEnabled": null, "displayName": "Taro Demo", "facsimileTelephoneNumber": null, "givenName": "Taro", "jobTitle": null, "lastDirSyncTime": null, "mail": "demouser01@o365demo01.onmicrosoft.com", "mailNickname": "demouser01", "mobile": null, "otherMails": [ ], "passwordPolicies": "DisablePasswordExpiration", "passwordProfile": null, "physicalDeliveryOfficeName": null, "postalCode": null, "preferredLanguage": "ja-JP", "provisionedPlans": [{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "MicrosoftCommunicationsOnline"},{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "exchange"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "exchange"},{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "MicrosoftOffice"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "SharePoint"},{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "SharePoint"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "SharePoint"} ], "provisioningErrors": [ ], "proxyAddresses": ["SMTP:demouser01@o365demo01.onmicrosoft.com" ], "state": null, "streetAddress": null, "surname": "Demo", "telephoneNumber": null, "usageLocation": "JP", "userPrincipalName": "demouser01@o365demo01.onmicrosoft.com"},{ "odata.type": "Microsoft.WindowsAzure.ActiveDirectory.User", "objectType": "User", "objectId": "234ddd85-8988-4335-a4a5-5b63fe5652b8", "accountEnabled": true, "assignedLicenses": [{ "disabledPlans": [ ], "skuId": "3b555118-da6a-4418-894f-7df1e2096870"} ], "assignedPlans": [{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Enabled", "service": "SharePoint", "servicePlanId": "c7699d2e-19aa-44de-8edf-1736da088ca1"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Enabled", "service": "exchange", "servicePlanId": "9aaf7827-d63c-4b61-89c3-182f06f82e5c"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Deleted", "service": "RMSOnline", "servicePlanId": "bea4c11e-220a-4e6d-8eb8-8ea15d019f90"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Deleted", "service": "MicrosoftOffice", "servicePlanId": "43de0ff5-c92c-492b-9116-175376d08c38"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Enabled", "service": "MicrosoftCommunicationsOnline", "servicePlanId": "0feaeb32-d00e-4d66-bd5a-43b5b83db82c"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Enabled", "service": "SharePoint", "servicePlanId": "e95bec33-7c88-4a70-8e19-b10bd9d0c014"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Deleted", "service": "SharePoint", "servicePlanId": "5dbe027f-2339-4123-9542-606e4d348a72"},{ "assignedTimestamp": "2015-04-06T09:50:09Z", "capabilityStatus": "Deleted", "service": "exchange", "servicePlanId": "efb87545-963c-4e0d-99df-69c6916d9eb0"} ], "city": "Demo-City", "country": null, "department": null, "dirSyncEnabled": null, "displayName": "Matsuzaki Tsuyoshi", "facsimileTelephoneNumber": null, "givenName": "Tsuyoshi", "jobTitle": null, "lastDirSyncTime": null, "mail": "tsmatsuz@o365demo01.onmicrosoft.com", "mailNickname": "tsmatsuz", "mobile": "+81 9011110000", "otherMails": ["tsmatsuz_demo@hotmail.com" ], "passwordPolicies": "DisablePasswordExpiration", "passwordProfile": null, "physicalDeliveryOfficeName": null, "postalCode": "1110000", "preferredLanguage": "ja-JP", "provisionedPlans": [{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "exchange"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "exchange"},{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "MicrosoftOffice"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "MicrosoftCommunicationsOnline"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "SharePoint"},{ "capabilityStatus": "Deleted", "provisioningStatus": "Success", "service": "SharePoint"},{ "capabilityStatus": "Enabled", "provisioningStatus": "Success", "service": "SharePoint"} ], "provisioningErrors": [ ], "proxyAddresses": ["SMTP:tsmatsuz@o365demo01.onmicrosoft.com" ], "state": "Tokyo", "streetAddress": "1-1-1, Demo-Street Demo-City", "surname": "Matsuzaki", "telephoneNumber": "09011112222", "usageLocation": "JP", "userPrincipalName": "tsmatsuz@o365demo01.onmicrosoft.com"} ]}
OData に対応しているので、下記の通り Query (検索) も可能です。(下記は、Mail Address が「tsmatsuz@o365demo01.onmicrosoft.com」の User を取得しています。)
Azure Active Directory Graph で使用可能なクエリーの内容は「MSDN : Azure AD Graph Common Queries」に記載されています。
GET https://graph.windows.net/o365demo01.onmicrosoft.com/users()?$filter=mail%20eq%20'tsmatsuz%40o365demo01.onmicrosoft.com'Authorization: Bearer {access token}api-version: 1.0
Graph API を使って更新処理 (追加、変更、削除) も可能です。
下記では、ObjectId が 234ddd85-8988-4335-a4a5-5b63fe5652b8 の User の DisplayName のみを変更 (Update) しています。
MERGE https://graph.windows.net/o365demo01.onmicrosoft.com/directoryObjects/234ddd85-8988-4335-a4a5-5b63fe5652b8/Microsoft.DirectoryServices.Userapi-version: 1.0Content-Type: application/json;odata=minimalmetadataAccept: application/json;odata=minimalmetadataAuthorization: Bearer {access token}{ "odata.type":"Microsoft.DirectoryServices.User", "displayName":"Tsuyoshi Matsuzaki"}
また、Graph API を使用して、ユーザー情報などの差分 (変更) の追跡が可能です。
例えば、差分情報の取得 (Differential Query) を使って、独自のユーザー管理システムとの (User 情報などの) 同期処理 (Sync) もプログラミングできます。(Office 365 Identity program で Certify された WS-Federation プロバイダーや Shibboleth 以外のカスタム・アプリケーションで同期をおこなう場合には、この方法を使用します。)
補足 : プログラミングの概念は、一般の Sync のプログラミングに類似しており、SkipToken という変更ポイントを管理するキーを生成し、このキーを元に、その時点から現在までの差分を取得できます。詳細は「Azure AD Graph API Differential Query」を参照してください。
この他に、Users エンティティなどの Store の拡張 (プロパティの追加など) や、Permission 管理、Application Role 管理などの細かな管理タスクも実行できます。(処理内容によっては、最新の api-version を使用してください。)
Graph Explorer を使用すると、Browser を使用して Graph API の Request / Response を簡単に確認できます。
また、「MSDN : Azure Graph REST APIs Reference」で Graph API を interactive に確認可能になりましたので、同様に Request / Response を簡単に確認できます。(2015/05/01 追記)
Azure Active Directory Graph Client Library
.NET (C# など) を使用している方は、NuGet から Azure Active Directory Graph Client Library (Microsoft.Azure.ActiveDirectory.GraphClient) を取得してプログラミングできます。(上述の ADAL と共に使用します。)
例えば、下記は、Mail Address が「tsmatsuz@o365demo01.onmicrosoft.com」の User を取得して、その User の DisplayName を Update するサンプル コードです。
...using Microsoft.IdentityModel.Clients.ActiveDirectory;using Microsoft.Azure.ActiveDirectory.GraphClient;...private async void button1_Click(object sender, EventArgs e){ Uri serviceRoot = new Uri(new Uri("https://graph.windows.net"),"o365demo01.onmicrosoft.com"); ActiveDirectoryClient cl = new ActiveDirectoryClient(serviceRoot,async () => await GetToken()); var u = await cl.Users.Where(user => user.Mail.Equals("tsmatsuz@o365demo01.onmicrosoft.com")).ExecuteSingleAsync(); u.DisplayName = "Tsuyoshi Matsuzaki"; await u.UpdateAsync(); MessageBox.Show("Finished !");}private Task<string> GetToken(){ AuthenticationContext context =new AuthenticationContext("https://login.microsoftonline.com/o365demo01.onmicrosoft.com"); AuthenticationResult assertion = context.AcquireToken("https://graph.windows.net","39ff4d28-9cba-448c-acae-612705e54257", // client idnew Uri("https://localhost/sampleapp")); return Task.Factory.StartNew<string>(() => assertion.AccessToken);}. . .
※ 変更履歴 :
2015/03/19 エンドポイントを https://login.windows.net から https://login.microsoftonline.com (新エンドポイント) に変更しました
2015/04/10 最新の情報に Update。また、Application スコープの認証方法についての解説は「Azure AD : Backend Server-Side アプリの開発 (Deamon, Service など)」を参照するように変更
2015/05/01 Interactive Graph API reference の記述を追加
2015/11/19 Microsoft Graph API について追記
2017/05/26 画面を新ポータル (https://portal.azure.com) に変更
Categories: Uncategorized
7 replies»