5/29-30 de:code セッション SV-007 “パワフル モバイル アプリ開発 ~ 最新 Microsoft Azure Mobile Services をフル活用しよう!~ ” フォローアップ (4)
皆様、こんにちは!多くの方に (1) (2) (3) を読んでいただいて、大変感謝しています。
今回は、4番目のセッションフォローアップである、Microsoft Azure Active Directory 連携、に行きたいと思います。
セッションでもご紹介した通り、主に、Azure ポータル上で必要な手順と、ADAL(Active Directory Authentication Library)を使ったネイティブアプリの認証コードの記述、に分かれますので、順にご紹介していきます。
1.Azure ポータル上で必要な手順ーWebアプリ(Mobile Services のプロキシであるWebSites)の登録
まず最初に、アプリが Azure Active Directory を認証プロバイダーとして使用してMobile Services にログインできるように登録する方法をご紹介します。
Azure ポータルにログインし、Mobile Services タブをクリックして、対象のMobile Services をクリックします。![image image](https://msdntnarchive.z22.web.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/22/83/metablogapi/3630.image_thumb_4B70B718.png)
Identity(ID) タブをクリックします。
Azure Active Directory の箇所まで、当該セクションをスクロールダウンし、リストされている アプリケーション URL をコピーします。
管理ポータルから Active Directory に移動し、自分で作った Active Directory をポイントします(まだ作ってない場合には、新規作成ですぐに作りましょう)。もちろん、ユーザーも登録しておく必要があります。
アプリケーション タブをクリックし、 アプリを 追加します。
画面下部の追加ボタンを押して、組織で開発中のアプリケーションを追加 をクリックします。
アプリケーションの追加ウィザードの中で、アプリケーションの名前を適当に入力し、Web Application 及びまたは Web API タイプを選択して続けます。
サインオン URL ボックスで、先述した Mobile Services の Active Directory IDプロバイダー設定からコピーした App ID を貼り付けます。同じく、アプリケーション ID/URI も同じものを張り付け、保存します。このアプリは、この URI を使って、シングルサインオンのリクエストを、Azure Active Directory に送信します。継続ボタンをクリックします。
アプリケーションが追加されたら、 構成タブをクリックします 。 そして、 発行されたクライアント ID をコピーします。
Mobile Services の ID タブに戻ります。画面下部に、Azure Active Directory 用の Client ID 設定がありますので、そこにこの値を張り付けてして保存します。
※ .NETバックエンドを採用している場合(本稿もそうです)、Allowed Tenants リストが見えます。ここですべてのドメインを登録する必要があります(例: contoso.onmicrosoft.com) 。これを使って Mobile Services が Allowed Tenants リストにアクセスします。この設定は、Node.js(JavaScript)バックエンドには適用されません。
保存すると、Azure Active Directory を使って、このアプリの認証を行うことができます。
2.Windows ストアアプリ Mobile Services クライアントによる Azure Active Directory へのシングルサインオン
Azure 管理ポータルで、Azure Active Directory に戻ります。アプリケーション タブをクリックし、アプリケーションを選択します。
マニフェストの管理をクリックして、マニフェストのダウンロードを選び、アプリケーションマニフェストをローカルに保存します。
Visual Studio でこのマニフェストファイルを開きます。ファイルの先頭にある、apPermissions 部分を探します。
1: "appPermissions": [],
この部分を適宜変更して保存します。PermissionId の部分はもちろんこのままではなく、適宜変更してください。
1: "appPermissions": [
2: {
3: "claimValue": "user_impersonation",
4: "description": "Allow the application access to the mobile service",
5: "directAccessGrantTypes": [],
6: "displayName": "Have full access to the mobile service",
7: "impersonationAccessGrantTypes": [
8: {
9: "impersonated": "User",
10: "impersonator": "Application"
11: }
12: ],
13: "isDisabled": false,
14: "origin": "Application",
15: "permissionId": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",
16: "resourceScopeType": "Personal",
17: "userConsentDescription": "Allow the application full access to the mobile service on your behalf",
18: "userConsentDisplayName": "Have full access to the mobile service"
19: }
20: ],
PermissionId は、エンドポイントの表示をクリックすると、取得できます。
Azure 管理ポータルで、当該アプリのためのマニフェスト管理 をもう一度選択して、マニフェストのアップロードを選択します。ローカルにある、更新された当該マニフェストファイルの位置を指定して、アップロードします。
Azure Active Directory へのストアアプリの登録
Azure Active Directory へのストアアプリの登録には、このアプリを、Windows ストアに関連付けして、Package Security Identifier (通称:SID) を取得する必要があります。この SID を、Azure Active Directory の中のネイティブアプリケーションの設定の中に登録します。
新しい名前を付けたストアアプリのストアとの関連付け
Visual Studio で、ストアアプリのプロジェクトを右クリックして、ストア → アプリケーションとストアとの関連付けを選択します。
Windowsストアデベロッパーセンターにログインします。アプリ名を適当に入力して、 アプリ名を予約します。セッションでもご紹介した通り、予約は1年間は有効です。ストアで公開しないにしても、予約はしておきましょう。
適当な名前を付けて、次へ をクリックします。アプリとストアでの名前との関連付けをするをクリックすると、パッケージ SID が取得できます。パッケージ SID を取得するため、Windows ストアアプリ開発者ポータルのダッシュボードにログオンし、対象アプリの編集をクリックします。
そしてサービスをクリックします。
ライブサービスのサイトに移動します。
パッケージ SID をコピーして、Azure Active Directory にペーストします。
ネイティブアプリの登録
Azure 管理ポータルで、 Azure Active Directory に移動し、 ディレクトリを展開します。
アプリケーション タブをクリックし、 アプリを 追加します。
画面下部の追加ボタンを押して、組織で開発中のアプリケーションを追加 をクリックします。
アプリケーションの追加ウィザードの中で、アプリケーションの名前を適当に入力し、ネイティブクライアントアプリケーションタイプを選択して続けます。
リダイレクト URI ボックスに、先ほどコピーした、パッケージ SID をペーストし、保存して登録を終了します。。
ネイティブアプリの構成 タブをクリックし、 クライアント ID をコピーします。後で必要となります(適宜、ロゴなどもアップロードします)。
ページをスクロールダウンして、他のアプリケーションに対するアクセス許可セクションに移動します。そして、該当する登録済み Mobile Services アプリケーションに対するフルアクセスを設定し、保存をクリックします。
これで、Mobile Services は、アプリからのログイン要求を、Azure Active Directory の中でシングルサインオンを要求するように、構成されました。
Mobile Services コントローラー側を認証を要求するように修正
ついで当該Mobile Services の .NET バックエンド側を、認証が必要なように、修正します。
.NET バックエンドのプロジェクトを開きます。ソリューションエクスプローラーで、Controllers フォルダを開き、 ProductWithPriceController.cs ファイルを開き、下記の通り、編集します。。
1: using Microsoft.WindowsAzure.Mobile.Service.Security;
ProductWithPriceController.cs ファイル内のすべてのメソッドに、 [AuthorizeLevel(AuthorizationLevel.User)] 属性を、追加して、保存します。プロジェクトを右クリックして、リビルドします。そして、Azure に、再度発行(パブリッシュ)します。
1: ・・・
2: // GET tables/ProductWithPrice
3: [RequiresAuthorization(AuthorizationLevel.User)]
4: public IQueryable<ProductWithPrice> GetAllProductWithPrice()
5: {
6: return Query();
7: }
8:
9: // GET tables/ProductWithPrice/48D68C86-6EA6-4C25-AA33-223FC9A27959
10: [RequiresAuthorization(AuthorizationLevel.User)]
11: public SingleResult<ProductWithPrice> GetProductWithPrice(string id)
12: {
13: return Lookup(id);
14: }
15:
16:
17: // PATCH tables/ProductWithPrice/48D68C86-6EA6-4C25-AA33-223FC9A27959
18: [RequiresAuthorization(AuthorizationLevel.User)]
19: public Task<ProductWithPrice> PatchProductWithPrice(string id, Delta<ProductWithPrice> patch)
20: {
21: return UpdateAsync(id, patch);
22: }
23:
24: [RequiresAuthorization(AuthorizationLevel.User)]
25: // POST tables/ProductWithPrice/48D68C86-6EA6-4C25-AA33-223FC9A27959
26: public async Task<IHttpActionResult> PostProductWithPrice(ProductWithPrice item)
27: {
28: ProductWithPrice current = await InsertAsync(item);
29: return CreatedAtRoute("Tables", new { id = current.Id }, current);
30: }
31:
32: [RequiresAuthorization(AuthorizationLevel.User)]
33: // DELETE tables/ProductWithPrice/48D68C86-6EA6-4C25-AA33-223FC9A27959
34: public Task DeleteProductWithPrice(string id)
35: {
36: return DeleteAsync(id);
37: }
38: ・・・
ストアアプリへの認証コードの追加
このままストアアプリを実行すると、当然ながら、401のエラー(Unauthorized)が返ってきます。
そこで、認証の ためのコードを追加します。ソリューションエクスプローラーで、ストアアプリのプロジェクトを右クリックして、NuGet パッケージの管理を右クリックします。
NuGet パッケージマネージャーのダイアログで、オンライン でプレリリースを含んだ形で、検索します。検索ボックス内に、Microsoft.IdentityModel.Clients と入力して、Active Directory Authentication Library が見つかったら、インストール をクリックして、Active Directory Authentication Library Nuget package をインストールします。
ソリューションエクスプローラーで、MainPage.xaml.cs を開いて、下記の using 句を追加します。
1: using Windows.UI.Popups;
2: using Microsoft.IdentityModel.Clients.ActiveDirectory;
3: using Newtonsoft.Json.Linq;
MainPage クラスに、AuthenticateAsync() メソッドを追加します。
1: private MobileServiceUser user;
2: private async Task AuthenticateAsync()
3: {
4: string authority = "<INSERT-AUTHORITY-HERE>";
5: string resourceURI = "<INSERT-RESOURCE-URI-HERE>";
6: string clientID = "<INSERT-CLIENT-ID-HERE>";
7: while (user == null)
8: {
9: string message;
10: try
11: {
12: AuthenticationContext ac = new AuthenticationContext(authority, false);
13: AuthenticationResult ar = await ac.AcquireTokenAsync(resourceURI, clientID);
14: JObject payload = new JObject();
15: payload["access_token"] = ar.AccessToken;
16: user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
17: message = string.Format("You are now logged in - {0}", user.UserId);
18: }
19: catch (InvalidOperationException)
20: {
21: message = "You must log in. Login Required";
22: }
23: var dialog = new MessageDialog(message);
24: dialog.Commands.Add(new UICommand("OK"));
25: await dialog.ShowAsync();
26: }
27: }
・INSERT-AUTHORITY-HERE は、テナント名です。フォーマットは、https://login.windows.net/tenant-name.onmicrosoft.com となります。こちらは、Azure ポータル内の Azure Active Directory から取得します。先ほども出てきました。
・INSERT-RESOURCE-URI-HERE は、Mobile Services の App ID URI です。プロキシサービスとして機能する Websites です。フォーマットは、 https://todolist.azure-mobile.net/login/aad となります。これも既出です。
・INSERT-CLIENT-ID-HERE の箇所は、Azure Active Directory で設定したネイティブクライアントアプリのページから、クライアント ID を取得してください。これも既出です。
Package.appxmanifest ファイルの設定
ソリューションエクスプローラーで、ストアアプリ内の Package.appxmanifest ファイルを開きます。機能タブを開いて、エンタープライズ認証と、プライベートネットワーク(クライアントとサーバー)にチェックをして保存します。
MainPage.cs に戻り、OnNavigatedTo イベントハンドラを、下記の通り編集し、AuthenticateAsync() メソッドを呼ぶように変更します。
1: protected override async void OnNavigatedTo(NavigationEventArgs e)
2: {
3: if (user == null)
4: await AuthenticateAsync();
5:
6: RefreshTodoItems();
7: }
アプリをリビルドして、実行し、このような画面が出てくればOKです。Azure Active Directory に作成済みのユーザーで、ログインしましょう。
なお、セッションでは、DEMOとして、これ以外に、Office 365 連携アプリ(SQL Database とExchange Online の両方に予定を書き込む) もご紹介しましたが、こちらは別途、サブスクリプションが必要となりますので、こちらは割愛します。興味のある方は、弊社エバンジェリスト・松崎のブログ等をご参照ください。また、資料には、このあたりのフローも入れてありますので、ご参考まで!
以上です。いかがでしたか?
次回は、最後の(5)、として、Xamarin 連携の箇所を簡単に取り上げて、このセッションのフォローアップを終了としたいと思います。
それでは、また!
鈴木 章太郎