2012年12月4日火曜日

[Office 365 & WAAD] Graph API を利用したアイデンティティ管理


Office 365 Advent Calendar および Windows Azure Advent Calendar 用のポストです。

まず、最初に何故 2 つの Advent Calendar へのクロスポストなのか?というあたりを解説するために、Office 365 と Windows Azure Active Directory の関係を解説して置くと、単純に Office 365 の アイデンティティ基盤が Windows Azure Active Directory だからです。

[図:Office 365 と Windows Azure Active Directory の関係]


Office 365 のユーザやグループの管理を行ったり、シングルサインオンを行う際は実際は Office 365 そのものではなく、Windows Azure Active Directory に対して操作をしている、ということです。

[表:Office 365 から見た Windows Azure Active Directory]

機能Office 365 から見た WAAD
シングルサインオン信頼するアイデンティティ・プロバイダ
⇒ここで認証されたユーザは信頼できる
ユーザ/グループ管理アイデンティティ・ストア
⇒このデータベースに保持されるユーザ情報(属性など)を利用する

さて、本日のお題です。

■Office 365 のユーザ管理の限界

これまで、Windows Azure Active Directory 上のアカウントを管理(追加・変更・削除・ライセンス割り当て等)を行おうと思うと、マイクロソフト公式のディレクトリ同期モジュールを使うか、個別に PowerShell で管理を行うしか方法はありませんでした。

参考:@IT / Office 365 とのアイデンティティ連携を実現する
   http://www.atmarkit.co.jp/ait/articles/1211/14/news069.html

   ディレクトリ同期ツールを使って Office 365 へのユーザ同期を行う
   http://idmlab.eidentity.jp/2011/04/office365.html


しかし、このディレクトリ同期ツール、現状ではそれなりに制限事項があります。
例を挙げると、以下のような事項が挙げられます。

・社内の Active Directory がマルチフォレスト構成だった場合、同期用のドメインを別途構築し、必要なアカウント情報を同期用ドメインに集める必要がある
・不要な(Office 365 を利用しない)ユーザでも同期してしまう(除外ルールの融通が利かない)
・ライセンス割り当ては個別に実施する必要がある
・50,000 オブジェクトまでの同期しかサポートされない
・メンバ数が 15,000 を超えるグループは同期出来ない
・認証プロキシサーバ以下の環境では使えない
 ※認証不要な Proxy 環境化では netsh コマンドで https プロキシ設定をすれば OK
・(当然ですが)Windows Server でしか動かない

結果として、ディレクトリ同期を行った後、Office 365 の管理コンソールで不要なユーザを消したり、PowerShell でライセンス割り当てをしたり、、、とそれなりに管理者には負荷がかかるのが現実だと思います。


そこで登場したのが Windows Azure Active Directory Graph API です。
現在はまだプレビューですが、Graph API は RESTful な API なのでプラットフォームに依存せずに利用することができますし、各アイデンティティ管理製品のカスタムアダプタとして容易に実装することが可能となります。

先日、本 blog でもこの API を利用して Windows Azure Active Directory 上のユーザ情報を取得する方法を紹介しましたが、今回は
・ユーザの作成
・ユーザの更新
・ライセンスの割り当て
・ユーザの削除
を紹介したいと思います。

参考:[WAAD] REST Client で Graph API を直接実行する
   http://idmlab.eidentity.jp/2012/09/waad-rest-client-graph-api.html


■Graph API を利用するための準備

Graph API を利用して Windows Azure Active Directory 上のアカウントを管理するためには、
・サービスプリンシパルの作成
・テナント ID の取得
・作成したサービスプリンシパルへ適切な権限の付与
という 2 つの作業が必要です。

まず、サービスプリンシパルを作成します。
MSOnline / MSOnlineExtended の 2 つのモジュールを読み込んだ状態の PowerShell (Microsoft Online Services Module for Windows PowerShell)から
Connect-MsolService
で MSOnline へ接続します。
その状態で、
New-MsolServicePrincipal -DisplayName "<任意の名前>" -ServicePrincipalNames @("<任意の名前>") -Type Symmetric -Usage Verify - StartDate -EndDate
と実行します。

すると、以下のような結果が取得できます。

The following symmetric key was created as one was not supplied 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

DisplayName           : <指定した名前>
ServicePrincipalNames : {<指定した名前>, }
ObjectId              : BBBBBBBBBBBBBBBBBBBBBBBB
AppPrincipalId        : CCCCCCCCCCCCCCCCCCCCCCCCC
TrustedForDelegation  : False
AccountEnabled        : True
Addresses             : {}
KeyType               : Symmetric
KeyId                 : DDDDDDDDDDDDDDDDDDDDDDDD
StartDate             : 2012/12/03 8:00:00
EndDate               : 2015/12/03 8:00:00
Usage                 : Verify



この中で必要なのが、実行結果内の
・AppPrincipalId
・SymmetricKey
・ObjectId
の 3 つです。

次に、作成した Office 365 テナントの ID を取得します。
これも同じく PowerShell で
(Get-MsolCompanyInformation).objectId
を実行して Guid を取得します。


さらに作成したサービスプリンシパルへの適切な権限を付与します。
Windows Azure Active Directory を操作するための権限は複数存在しますが、ユーザを管理するために必要な権限は User Account Administrator というロールが持っていますので、作成したサービスプリンシパルをこのロールメンバに追加します。
同じく PowerShell で
Add-MsolRoleMember -RoleMemberType ServicePrincipal -RoleName "User Account Administrator" -RoleMemberObjectId <サービスプリンシパルの ObjectID>
と実行します。



ここまでそろえばあとは Graph API を実行するだけなのですが、実行するために必要なアクセストークンを取得する必要があります。
ここも RESTful API を使って取得することも可能ですが、今回は面倒なので Windows Azure Authentication Library (AAL) を使ってアクセストークンを取得するプログラムを書いてみます。

参考:Windows Azure Authentication Library
   http://msdn.microsoft.com/en-us/library/windowsazure/jj573266.aspx

   ※ちなみに AAL を使わずにアクセストークンを取得する方法は先に挙げたポストを参照してください。
   [WAAD] REST Client で Graph API を直接実行する
   http://idmlab.eidentity.jp/2012/09/waad-rest-client-graph-api.html


今回は簡単なプログラムを書きました。
using System;
using Microsoft.WindowsAzure.ActiveDirectory.Authentication;

namespace GetAccessToken
{
    class Program
    {
        static void Main(string[] args)
        {
            string TenantDomainName = "<取得したテナントドメイン名>.onmicrosoft.com";
            string TenantId = "<取得したテナントID>";
            string AppPrincipalId = "<取得した AppPrincipalId";
            string SymmetricKey = "<取得した SymmetricKey>";

            AuthenticationContext context = new AuthenticationContext(
                "https://accounts.accesscontrol.windows.net/" + TenantDomainName);
            SymmetricKeyCredential credential = new SymmetricKeyCredential(
                AppPrincipalId + "@" + TenantId,
                Convert.FromBase64String(SymmetricKey));
            AssertionCredential assertion = context.AcquireToken(
                "00000002-0000-0000-c000-000000000000/directory.windows.net@" + TenantId, credential);
            System.Console.WriteLine("auth:" + assertion.CreateAuthorizationHeader());

        }
    }
}



このプログラムをコンパイルして実行すると Windows Azure Active Directory から Graph API 実行に必要なアクセストークンを取得し、コンソールに表示してくれますので、メモしておきます。

いよいよ Graph API の実行です。今回も先のポストと同様に Chrome Extension の Advanced Rest Client を使いました。


■Graph API でユーザを作成する
まずはユーザの作成です。
実行するクエリをまとめると以下の表になります。

設定
エンドポイントhttps://graph.windows.net/advent2012.onmicrosoft.com/Users
メソッドPOST
ヘッダAuthorization取得したアクセストークン
x-ms-dirapi-data-contract-version0.8
Content-Typeapplication/atom+xml
ボディ<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<content type="application/xml">
<m:properties>
<d:ObjectType>User</d:ObjectType>
<d:AccountEnabled m:type="Edm.Boolean">true</d:AccountEnabled>
<d:DisplayName>織田信長</d:DisplayName>
<d:GivenName>信長</d:GivenName>
<d:Surname>織田</d:Surname>
<d:UserPrincipalName>nobunagao@<テナントドメイン名>.onmicrosoft.com</d:UserPrincipalName>
<d:MailNickname>nobunagao</d:MailNickname>
<d:Password>P@ssw0rd</d:Password>
</m:properties>
</content>
</entry>


うまくいくと HTTP 201 created が返され、作成されたユーザエントリの情報が XML (Accept ヘッダを application/json にしておけば JSON )で返ってきます。


■Graph API でユーザを更新する
次に作成したユーザの属性を更新してみます。
作成時に UsageLocale を指定しなかったので、次のライセンス割り当てで問題が起きるため、UsageLocale 属性を更新してみます。(ライセンス割り当てにはユーザの所在地の指定が必要)

今回は PATCH メソッドを利用します。

設定
エンドポイントhttps://graph.windows.net/advent2012.onmicrosoft.com/Users(‘<対象ユーザ名>@<テナントドメイン>.onmicrosoft.com’)
メソッドPATCH
ヘッダAuthorization取得したアクセストークン
x-ms-dirapi-data-contract-version0.8
Content-Typeapplication/atom+xml
ボディ<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<content type="application/xml">
<m:properties>
<d:UsageLocation>JP </d:UsageLocation>
</m:properties>
</content>
</entry>



うまくいくと HTTP 204 no-content が返されます。


■Graph API でライセンスを割り当てる
作成したユーザにはまだライセンスを割り当てていないので、ライセンスの割り当てを行います。
今回は Office 365 のプラン E3 を使ったので、該当する SkuId である「6fd2c87f-b296-42f0-b197-1e91e994b900」を割り当てます。

設定
エンドポイントhttps://directory.windows.net/<取得したテナントドメイン>.onmicrosoft.com/Users('<割り当てるユーザID>@<取得したテナントドメイン>.onmicrosoft.com')/AssignLicense
メソッドPOST
ヘッダAuthorization取得したアクセストークン
x-ms-dirapi-data-contract-version0.8
Content-Typeapplication/json;odata=verbose;charset=utf-8
ボディ{"AddLicenses":
[
{
"__metadata":
{"type":"Microsoft.WindowsAzure.ActiveDirectory.AssignedLicense"},
"DisabledPlans":
{"__metadata":
{"type":"Collection(Edm.Guid)"},
"results":[]},
"SkuId":"6fd2c87f-b296-42f0-b197-1e91e994b900"
}
],
"RemoveLicenses":null
}


うまくいくと HTTP 200 ok が返され、アサインされたライセンスを含むユーザエントリ情報が XML もしくは JSON で返ってきます。
よく見ると RMSOnline なんていう文字列も見えるので、Office 365 の管理ポータルから見える以外のライセンスの準備も進んでいることがよくわかります。


■Graph API でユーザを削除する
最後に作成したユーザを削除してみます。
以下のクエリを実行します。

設定
エンドポイントhttps://graph.windows.net/advent2012.onmicrosoft.com/Users(‘<作成したユーザID>@<テナントドメイン>.onmicrosoft.com’)
メソッドDELETE
ヘッダAuthorization取得したアクセストークン
x-ms-dirapi-data-contract-version0.8
Content-Typeapplication/x-www-form-urlencoded?


こちらもうまくいくと HTTP 204 no-content が返ってきます。





いかがでしたでしょうか?
まだまだプレビューですので、色々と検証してみる必要はありそうですが、上記のように公式のディレクトリ同期ツールを使わなくても Graph API を実行することによりアイデンティティ管理を柔軟に行うことが可能になることがわかりました。
私も Forefront Identity Manager 2010 用の Windows Azure Active Directory 用のカスタム管理エージェントを作ってみようとしているところなので、また完成したら公開したいと思います。


以上で私のポストはおしまいですが、明日は各 Advent Calendar は以下の予定になっているそうなので、引き続き参考にしてみてください。
・Office 365 : Office 365 MVP 中村 和彦さん / http://simplesso.jp/
・Windows Azure : Kentaro AOKIさん / http://kentablog.cluscore.com/

0 件のコメント: