次の方法で共有


Windows アプリに認証を追加する

概要

このトピックでは、モバイル アプリにクラウドベースの認証を追加する方法について説明します。 このチュートリアルでは、Azure App Service でサポートされている ID プロバイダーを使用して、Mobile Apps のユニバーサル Windows プラットフォーム (UWP) クイック スタート プロジェクトに認証を追加します。 モバイル アプリ バックエンドによって正常に認証および承認されると、ユーザー ID 値が表示されます。

このチュートリアルは、Mobile Apps のクイックスタートに基づいています。 最初に、Mobile Apps の概要を把握するチュートリアルを完了する必要があります。

認証用にアプリを登録し、App Service を構成する

まず、ID プロバイダーのサイトでアプリを登録する必要があります。次に、Mobile Apps バックエンドでプロバイダーによって生成された資格情報を設定します。

  1. プロバイダー固有の手順に従って、優先 ID プロバイダーを構成します。

  2. アプリでサポートするプロバイダーごとに、前の手順を繰り返します。

許可された外部リダイレクト URL にアプリを追加する

セキュリティで保護された認証では、アプリの新しい URL スキームを定義する必要があります。 これにより、認証プロセスが完了すると、認証システムはアプリにリダイレクトし直すことができます。 このチュートリアルでは、appname のURLスキームを全体にわたって使用します。 ただし、選択した任意の URL スキームを使用できます。 モバイル アプリケーションに固有である必要があります。 サーバー側でリダイレクトを有効にするには:

  1. Azure portalで、App Service を選択します。

  2. 認証/承認 メニュー オプションをクリックします。

  3. 許可された外部リダイレクト URLに、「url_scheme_of_your_app://easyauth.callback」と入力します。 この文字列の url_scheme_of_your_app は、モバイル アプリケーションの URL スキームです。 プロトコルの通常の URL 仕様に従う必要があります (文字と数字のみを使用し、文字で始めます)。 複数の場所で URL スキームを使用してモバイル アプリケーション コードを調整する必要がある場合は、選択した文字列を書き留める必要があります。

  4. [保存] をクリックします。

認証されたユーザーにアクセス許可を制限する

既定では、Mobile Apps バックエンドの API は匿名で呼び出すことができます。 次に、認証されたクライアントのみにアクセスを制限する必要があります。

  • バックエンド Node.js (Azure portal 経由):

    Mobile Apps の設定で、[簡単なテーブル] クリックし、テーブルを選択します。 [アクセス許可 変更] をクリックし、すべてのアクセス許可 [認証済みアクセスのみ] を選択し、[の保存]クリックします。

  • .NET バックエンド (C#) :

    サーバー プロジェクトで、Controllers>TodoItemController.csに移動します。 次のように、TodoItemController クラスに [Authorize] 属性を追加します。 特定のメソッドにのみアクセスを制限するには、クラスではなく、これらのメソッドにのみこの属性を適用することもできます。 サーバープロジェクトを再公開します。

      [Authorize]
      public class TodoItemController : TableController<TodoItem>
    
  • バックエンド Node.js (Node.js コード経由):

    テーブル アクセスの認証を要求するには、Node.js サーバー スクリプトに次の行を追加します。

      table.access = 'authenticated';
    

    詳細については、「方法:テーブルへのアクセスに認証を要求する」を参照してください。 サイトからクイック スタート コード プロジェクトをダウンロードする方法については、「方法: Gitを使用して Node.js バックエンド クイックスタート コード プロジェクトをダウンロードする」を参照してください。

これで、バックエンドへの匿名アクセスが無効になっていることを確認できます。 UWP アプリ プロジェクトをスタートアップ プロジェクトとして設定した状態で、アプリを展開して実行します。アプリの起動後に状態コード 401 (Unauthorized) を持つ未処理の例外が発生することを確認します。 これは、アプリが認証されていないユーザーとしてモバイル アプリ コードにアクセスしようとしたが、TodoItem テーブルで認証が必要になったためです。

次に、App Service にリソースを要求する前に、ユーザーを認証するようにアプリを更新します。

アプリに認証を追加する

  1. UWP アプリ プロジェクト ファイルにMainPage.xaml.csし、次のコード スニペットを追加します。

     // Define a member variable for storing the signed-in user. 
     private MobileServiceUser user;
    
     // Define a method that performs the authentication process
     // using a Facebook sign-in. 
     private async System.Threading.Tasks.Task<bool> AuthenticateAsync()
     {
         string message;
         bool success = false;
         try
         {
             // Change 'MobileService' to the name of your MobileServiceClient instance.
             // Sign-in using Facebook authentication.
             user = await App.MobileService
                 .LoginAsync(MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}");
             message =
                 string.Format("You are now signed in - {0}", user.UserId);
    
             success = true;
         }
         catch (InvalidOperationException)
         {
             message = "You must log in. Login Required";
         }
    
         var dialog = new MessageDialog(message);
         dialog.Commands.Add(new UICommand("OK"));
         await dialog.ShowAsync();
         return success;
     }
    

    このコードは、Facebook ログインを使用してユーザーを認証します。 Facebook 以外の ID プロバイダーを使用している場合は、上記 MobileServiceAuthenticationProvider の値をプロバイダーの値に変更します。

  2. MainPage.xaml.csの OnNavigatedTo() メソッドを置き換えます。 次に、認証をトリガーするアプリに サインイン ボタンを追加します。

     protected override async void OnNavigatedTo(NavigationEventArgs e)
     {
         if (e.Parameter is Uri)
         {
             App.MobileService.ResumeWithURL(e.Parameter as Uri);
         }
     }
    
  3. MainPage.xaml.csに次のコード スニペットを追加します。

     private async void ButtonLogin_Click(object sender, RoutedEventArgs e)
     {
         // Login the user and then load data from the mobile app.
         if (await AuthenticateAsync())
         {
             // Switch the buttons and load items from the mobile app.
             ButtonLogin.Visibility = Visibility.Collapsed;
             ButtonSave.Visibility = Visibility.Visible;
             //await InitLocalStoreAsync(); //offline sync support.
             await RefreshTodoItems();
         }
     }
    
  4. MainPage.xaml プロジェクト ファイルを開き、[保存] ボタンを定義する要素を見つけて、次のコードに置き換えます。

     <Button Name="ButtonSave" Visibility="Collapsed" Margin="0,8,8,0" 
             Click="ButtonSave_Click">
         <StackPanel Orientation="Horizontal">
             <SymbolIcon Symbol="Add"/>
             <TextBlock Margin="5">Save</TextBlock>
         </StackPanel>
     </Button>
     <Button Name="ButtonLogin" Visibility="Visible" Margin="0,8,8,0" 
             Click="ButtonLogin_Click" TabIndex="0">
         <StackPanel Orientation="Horizontal">
             <SymbolIcon Symbol="Permissions"/>
             <TextBlock Margin="5">Sign in</TextBlock> 
         </StackPanel>
     </Button>
    
  5. App.xaml.csに次のコード スニペットを追加します。

     protected override void OnActivated(IActivatedEventArgs args)
     {
         if (args.Kind == ActivationKind.Protocol)
         {
             ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;
             Frame content = Window.Current.Content as Frame;
             if (content.Content.GetType() == typeof(MainPage))
             {
                 content.Navigate(typeof(MainPage), protocolArgs.Uri);
             }
         }
         Window.Current.Activate();
         base.OnActivated(args);
     }
    
  6. Package.appxmanifest ファイルを開き、宣言に移動 、[使用可能な宣言] ドロップダウン リストで[プロトコル 選択し、[の追加] ボタン クリックします。 次に、プロトコルの 宣言の プロパティ を構成します。 表示名で、アプリケーションのユーザーに表示する名前を追加します。 名前に、{url_scheme_of_your_app} を追加してください。

  7. F5 キーを押してアプリを実行し、サインイン ボタンをクリックし、選択した ID プロバイダーを使用してアプリにサインインします。 サインインが成功すると、アプリはエラーなしで実行され、バックエンドに対してクエリを実行し、データを更新できます。

認証トークンをクライアントに格納する

前の例では、標準のサインインを示しました。このサインインでは、アプリが起動するたびにクライアントが ID プロバイダーと App Service の両方に接続する必要があります。 この方法は非効率的であるだけでなく、多くのお客様が同時にアプリを起動しようとすると、使用状況に関連する問題が発生する可能性があります。 より良い方法は、App Service によって返された承認トークンをキャッシュし、プロバイダーベースのサインインを使用する前に最初にこれを使用することです。

クライアント管理認証とサービス管理認証のどちらを使用しているかに関係なく、App Services によって発行されたトークンをキャッシュできます。 このチュートリアルでは、サービス管理認証を使用します。

  1. MainPage.xaml.cs プロジェクト ファイルで、ステートメントを使用して次の を追加します。

     using System.Linq;        
     using Windows.Security.Credentials;
    
  2. AuthenticateAsync メソッドを次のコードに置き換えます。

     private async System.Threading.Tasks.Task<bool> AuthenticateAsync()
     {
         string message;
         bool success = false;
    
         // This sample uses the Facebook provider.
         var provider = MobileServiceAuthenticationProvider.Facebook;
    
         // Use the PasswordVault to securely store and access credentials.
         PasswordVault vault = new PasswordVault();
         PasswordCredential credential = null;
    
         try
         {
             // Try to get an existing credential from the vault.
             credential = vault.FindAllByResource(provider.ToString()).FirstOrDefault();
         }
         catch (Exception)
         {
             // When there is no matching resource an error occurs, which we ignore.
         }
    
         if (credential != null)
         {
             // Create a user from the stored credentials.
             user = new MobileServiceUser(credential.UserName);
             credential.RetrievePassword();
             user.MobileServiceAuthenticationToken = credential.Password;
    
             // Set the user from the stored credentials.
             App.MobileService.CurrentUser = user;
    
             // Consider adding a check to determine if the token is 
             // expired, as shown in this post: https://aka.ms/jww5vp.
    
             success = true;
             message = string.Format("Cached credentials for user - {0}", user.UserId);
         }
         else
         {
             try
             {
                 // Sign in with the identity provider.
                 user = await App.MobileService
                     .LoginAsync(provider, "{url_scheme_of_your_app}");
    
                 // Create and store the user credentials.
                 credential = new PasswordCredential(provider.ToString(),
                     user.UserId, user.MobileServiceAuthenticationToken);
                 vault.Add(credential);
    
                 success = true;
                 message = string.Format("You are now signed in - {0}", user.UserId);
             }
             catch (MobileServiceInvalidOperationException)
             {
                 message = "You must sign in. Sign-In Required";
             }
         }
    
         var dialog = new MessageDialog(message);
         dialog.Commands.Add(new UICommand("OK"));
         await dialog.ShowAsync();
    
         return success;
     }
    

    このバージョンの AuthenticateAsyncでは、アプリは、PasswordVault に格納されている資格情報を使用してサービスにアクセスしようとします。 通常のサインインは、保存されている資格情報がない場合にも実行されます。

    キャッシュされたトークンの有効期限が切れる可能性があり、トークンの有効期限は、アプリが使用されているときに認証後にも発生する可能性があります。 トークンの有効期限が切れているかどうかを確認する方法については、「認証トークンの有効期限が切れていないかどうかを確認する」を参照してください。 トークンの期限切れに関連する承認エラーを処理するソリューションについては、Azure Mobile Services マネージド SDK でのキャッシュと期限切れのトークンの処理に関する投稿を参照してください。

  3. アプリを 2 回再起動します。

    最初の起動時に、プロバイダーへのサインインが再び必要であることに注意してください。 ただし、2 回目の再起動では、キャッシュされた資格情報が使用され、サインインはバイパスされます。

次のステップ

この基本認証チュートリアルを完了したので、次のいずれかのチュートリアルに進んでください。

  • プッシュ通知をアプリ に追加する
    プッシュ通知のサポートをアプリに追加し、Azure Notification Hubs を使用してプッシュ通知を送信するようにモバイル アプリ バックエンドを構成する方法について説明します。
  • アプリ のオフライン同期を有効にする
    モバイル アプリ バックエンドを使用してアプリのオフライン サポートを追加する方法について説明します。 オフライン同期を使用すると、エンド ユーザーは、ネットワーク接続がない場合でも、モバイル アプリを操作できます (データの表示、追加、変更)。