Android デバイスの共有デバイス モード

小売関係者、フライト クルー、フィールド サービス ワーカーなどの現場担当者は、多くの場合、共有モバイル デバイスを使用して作業を実行します。 これらの共有デバイスは、ユーザーが自分のパスワードや PIN を意図的に共有したり、共有デバイス上の顧客データやビジネス データにアクセスしたりする場合に、セキュリティ 上のリスクを引き出す可能性があります。

共有デバイス モード では、従業員がデバイスを安全に共有できるように Android 8.0 以降のデバイスを構成できます。 従業員は 1 回サインインして、この機能をサポートするすべてのアプリにシングル サインオン (SSO) を行い、情報にすばやくアクセスできます。 シフトまたはタスクの完了後に従業員がサインアウトすると、デバイスとサポートされているすべてのアプリケーションから自動的にサインアウトされ、デバイスは次のユーザーに対応できるようになります。

共有デバイス モード機能を利用するには、アプリ開発者とクラウド デバイス管理者が連携して作業します。

  1. デバイス管理者は、デバイスを手動で共有するか、Microsoft Intuneなどのモバイル デバイス管理 (MDM) プロバイダーを使用してデバイスを準備します。 推奨されるオプションは、MDM を使用することです。これにより、ゼロタッチ プロビジョニングを使用して共有デバイス モードで大規模にデバイスをセットアップできます。 MDM は、Microsoft Authenticator アプリをデバイスにプッシュし、デバイスへのマネージド構成の更新を通じて各デバイスの "共有モード" をオンにします。 この共有モード設定は、デバイスでサポートされているアプリの動作を変更します。 MDM プロバイダーからのこの構成は、デバイスの共有デバイス モードを設定し、Authenticator アプリを使用して共有デバイスの登録をトリガーします。

  2. アプリケーション開発者は 、次のシナリオを処理するために、単一アカウント アプリを作成します (複数アカウント アプリは共有デバイス モードではサポートされていません)。

    • サポートされているアプリケーションを使用して、デバイス全体でユーザーをサインインする
    • サポートされているアプリケーションを使用して、デバイス全体でユーザーをサインアウトする
    • デバイスの状態を照会して、アプリケーションが共有デバイス モードのデバイス上にあるかどうかを判断する
    • ユーザーのデバイスの状態を照会して、前回の使用以降のアプリケーションの変更を確認します

    共有デバイス モードのサポートは、アプリケーションの機能アップグレードと見なす必要があり、複数のユーザー間で同じデバイスが使用されている環境での導入を増やすのに役立ちます。

    Important

    Android で共有デバイス モードをサポートするMicrosoftアプリケーションは、変更を必要とせず、共有デバイス モードに付属する利点を得るためにデバイスにインストールする必要があります。

共有デバイス モードでデバイスを設定する

共有デバイス モードをサポートするように Android デバイスを構成するには、Android OS 8.0 以降を実行している必要があります。 また、デバイスは、工場出荷時の設定にリセットするか、Microsoft アプリおよび共有デバイス モードが有効なその他すべてのアプリをアンインストールして再インストールすることによって、消去する必要があります。

Microsoft Intuneでは、Microsoft Entra共有デバイス モードのデバイスに対するゼロタッチ プロビジョニングがサポートされています。つまり、現場担当者からの最小限の操作でデバイスをセットアップして Intune に登録できます。 Microsoft Intuneを MDM として使用するときに共有デバイス モードでデバイスを設定するには、「Microsoft Entra共有デバイス モードでデバイスの登録を設定する」を参照してください。

共有デバイス モードをサポートするように Android アプリケーションを変更する

ユーザーは、自分のデータが他のユーザーに漏えいしないよう、あなたが確実に守ることを期待しています。 次のセクションでは、変更が発生し、処理する必要があることをアプリケーションに示すために役立つシグナルを提供します。 アプリが使用されるたびにデバイス上のユーザーの状態を確認し、前のユーザーのデータをクリアする責任があります。 これには、マルチタスクでバックグラウンドから再読み込みされる場合も含まれます。 ユーザーの変更時に、前のユーザーのデータがクリアされていることと、アプリケーションに表示されているキャッシュされたデータが削除されていることを確認する必要があります。 共有デバイス モードをサポートするようにアプリを更新した後、お客様と会社でセキュリティ レビュー プロセスを実施することを強くお勧めします。

アプリケーションの依存関係に Microsoft Authentication Library (MSAL) SDK を追加する

次のように、MSAL ライブラリを依存関係として build.gradle ファイルに追加します。

dependencies{
  implementation 'com.microsoft.identity.client.msal:5.+'
}

共有デバイス モードを使用するようアプリを構成する

Microsoft Authentication Library (MSAL) SDK を使用して記述されたアプリケーションは、単一のアカウントまたは複数のアカウントを管理できます。 詳細については、 単一アカウント モードまたは複数アカウント モードを参照してください。 共有デバイス モード アプリは、単一アカウント モードでのみ動作します。

複数アカウント モードをサポートする予定がない場合は、msal 構成ファイルで "account_mode""SINGLE" に設定します。 これにより、お客様のアプリで常に ISingleAccountPublicClientApplication が取得されるようになり、MSAL の統合が大幅に簡素化されます。 "account_mode" の既定値は "MULTIPLE" であるため、"single account" モードを使用する場合は、構成ファイルでこの値を変更することが重要です。

構成ファイルの例を次に示します。

{
  "client_id": "Client ID after app registration at https://aka.ms/MobileAppReg",
  "authorization_user_agent": "WEBVIEW",
  "redirect_uri": "Redirect URI after app registration at https://aka.ms/MobileAppReg",
  "account_mode": "SINGLE",
  "broker_redirect_uri_registered": true,
  "authorities": [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

構成ファイルの設定の詳細については、 構成ドキュメント を参照してください。

単一アカウントと複数アカウントの両方のサポート

アプリは、個人デバイスと共有デバイスの両方での実行をサポートするように構築できます。 現在、アプリが複数のアカウントをサポートしており、共有デバイス モードをサポートするようにしたい場合は、単一アカウント モードのサポートを追加してください。

アプリが実行されているデバイスの種類に応じて、アプリの動作を変えたい場合もあるでしょう。 いつ単一アカウント モードで実行するかを決定するには、ISingleAccountPublicClientApplication.isSharedDevice() を使用します。

アプリケーションが実行しているデバイスの種類を表す 2 つの異なるインターフェイスが存在します。 MSAL のアプリケーション ファクトリにアプリケーション インスタンスを要求すると、適切なアプリケーション オブジェクトが自動的に提供されます。

次のオブジェクト モデルは、受信する可能性のあるオブジェクトの型と、それが共有デバイスのコンテキストで何を示すかを示しています。

パブリック クライアント アプリケーションの継承モデル

PublicClientApplication オブジェクトを取得したら、型のチェックを行い、適切なインターフェイスにキャストする必要があります。 次のコードは、複数アカウント モードまたは単一アカウント モードをチェックし、アプリケーション オブジェクトを適切にキャストします。

private IPublicClientApplication mApplication;

        // Running in personal-device mode?
        if (mApplication instanceOf IMultipleAccountPublicClientApplication) {
          IMultipleAccountPublicClientApplication multipleAccountApplication = (IMultipleAccountPublicClientApplication) mApplication;
          ...
        // Running in shared-device mode?
        } else if (mApplication instanceOf ISingleAccountPublicClientApplication) {
           ISingleAccountPublicClientApplication singleAccountApplication = (ISingleAccountPublicClientApplication) mApplication;
            ...
        }

アプリが共有デバイスまたは個人デバイスのどちらで実行されているかに応じて、次の違いが適用されます。

共有モードのデバイス 個人デバイス
アカウント 1 つのアカウント 複数のアカウント
サインイン グローバル グローバル
サインアウト グローバル 各アプリケーションは、サインアウトがアプリに対してローカルかどうかを制御できます。
サポートされているアカウントの種類 職場アカウントのみ サポートされている個人アカウントと業務用アカウント

PublicClientApplication オブジェクトを初期化する

MSAL 構成ファイルで "account_mode":"SINGLE" を設定した場合、返されるアプリケーション オブジェクトを ISingleAccountPublicCLientApplication として安全にキャストできます。

private ISingleAccountPublicClientApplication mSingleAccountApp;

PublicClientApplication.create(
    this.getApplicationCOntext(),
    R.raw.auth_config_single_account,
    new PublicClientApplication.ApplicationCreatedListener() {

        @Override
        public void onCreated(IPublicClientApplication application){
            mSingleAccountApp = (ISingleAccountPublicClientApplication)application;
        }

        @Override
        public void onError(MsalException exception){
            /*Fail to initialize PublicClientApplication */
        }
    });

共有デバイス モードを検出する

共有デバイス モードの検出は、アプリケーションにとって重要です。 多くのアプリケーションでは、共有デバイスでアプリケーションを使用するときに、ユーザー エクスペリエンス (UX) を変更する必要があります。 たとえば、アプリケーションに "サインアップ" 機能があるとします。これは、既にアカウントを持っている可能性があるため、現場担当者には適していません。 共有デバイス モードの場合は、アプリケーションのデータ処理にセキュリティを強化することもできます。

isSharedDeviceIPublicClientApplication API を使用して、アプリが共有デバイス モードでデバイスで実行されているかどうかを判断します。

次のコード スニペットは、 isSharedDevice API の使用例を示しています。

deviceModeTextView.setText(mSingleAccountApp.isSharedDevice() ? "Shared" : "Non-Shared");

サインインしているユーザーを取得し、ユーザーがデバイスで変更されたかどうかを判断する

共有デバイス モードをサポートするもう 1 つの重要な部分は、デバイス上のユーザーの状態を判断し、ユーザーが変更された場合、またはデバイスにユーザーがまったくいない場合にアプリケーション データをクリアすることです。 データが別のユーザーに漏洩しないようにする責任があります。

getCurrentAccountAsync API を使用して、デバイスで現在サインインしているアカウントに対してクエリを実行できます。

loadAccount メソッドでは、サインインしているユーザーのアカウントを取得します。 onAccountChanged メソッドでは、サインインしているユーザーが変更されたかどうかを特定し、その場合はクリーンアップします。

private void loadAccount()
{
  mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback())
  {
    @Override
    public void onAccountLoaded(@Nullable IAccount activeAccount)
    {
      if (activeAccount != null)
      {
        signedInUser = activeAccount;
        final AcquireTokenSilentParameters silentParameters = new AcquireTokenSilentParameters.Builder()
                        .fromAuthority(signedInUser.getAuthority())
                        .forAccount(signedInUser)
                        .withScopes(Arrays.asList(getScopes()))
                        .withCallback(getAuthSilentCallback())
                        .build();
        mSingleAccountApp.acquireTokenSilentAsync(silentParameters);
      }
    }
    @Override
    public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable Iaccount currentAccount)
    {
      if (currentAccount == null)
      {
        //Perform a cleanup task as the signed-in account changed.
        cleaUp();
      }
    }
    @Override
    public void onError(@NonNull Exception exception)
    {
        //getCurrentAccountAsync failed
    }
  }
}

ユーザーをグローバルにサインインさせる

デバイスが共有デバイスとして構成されている場合、アプリケーションは signIn API を呼び出してアカウントにサインインできます。 アカウントは、最初のアプリがアカウントにサインインした後、デバイス上のすべての対象アプリでグローバルに利用できるようになります。

final SignInParameters signInParameters = ... /* create SignInParameters object */
mSingleAccountApp.signIn(signInParameters);

ユーザーをグローバルにサインアウトさせる

次のコードは、サインインしているアカウントを削除し、キャッシュされたトークンをアプリだけでなく、共有デバイス モードのデバイスからもクリアします。 ただし、アプリケーションから データ をクリアすることはありません。 アプリケーションからデータをクリアし、アプリケーションがユーザーに表示している可能性があるキャッシュされたデータをクリアする必要があります。

mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() {
    @Override
    public void onSignOut() {
        // clear data from your application
    }

    @Override
    public void onError(@NonNull MsalException exception) {
        // signout failed, show error
    }
});

ブロードキャストを受信して、他のアプリケーションから開始されたグローバル サインアウトを検出する

アカウント変更ブロードキャストを受信するには、ブロードキャスト レシーバーを登録する必要があります。 コンテキストに登録されたレシーバーを介してブロードキャスト レシーバーを登録することをお勧めします。

アカウント変更ブロードキャストを受信したら、すぐに サインインしているユーザーを取得し、デバイスでユーザーが変更されたかどうかを判断します。 変更が検出された場合は、前にサインインしていたアカウントのデータのクリーンアップを開始します。 すべての操作を適切に停止し、データのクリーンアップを行うことをお勧めします。

次のコード スニペットは、ブロードキャスト レシーバーを登録する方法を示しています。

private static final String CURRENT_ACCOUNT_CHANGED_BROADCAST_IDENTIFIER = "com.microsoft.identity.client.sharedmode.CURRENT_ACCOUNT_CHANGED";
private BroadcastReceiver mAccountChangedBroadcastReceiver;
private void registerAccountChangeBroadcastReceiver(){
    mAccountChangedBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //INVOKE YOUR PRIOR ACCOUNT CLEAN UP LOGIC HERE
        }
    };
    IntentFilter filter = new

    IntentFilter(CURRENT_ACCOUNT_CHANGED_BROADCAST_IDENTIFIER);
    this.registerReceiver(mAccountChangedBroadcastReceiver, filter);
}

共有デバイス モードをサポートする Microsoft アプリケーション

次のMicrosoft アプリケーションでは、共有デバイス モードMicrosoft Entraサポートされています。

共有デバイス モードをサポートするサード パーティの MMM

次のサード パーティ製モバイル デバイス管理 (MDM) プロバイダーは、共有デバイス モードMicrosoft Entraサポートしています。

共有デバイスのサインアウトとアプリのライフサイクル全体

ユーザーがサインアウトしたら、ユーザーのプライバシーとデータを保護するためのアクションを実行する必要があります。 たとえば、医療記録アプリを作成する場合は、ユーザーが以前に表示された患者レコードをサインアウトしたときにクリアされるようにする必要があります。 アプリケーションは、データのプライバシーのために準備し、フォアグラウンドに入るたびに確認する必要があります。

アプリで MSAL を使用して、共有モードのデバイスで実行されているアプリでユーザーをサインアウトすると、サインインしたアカウントとキャッシュされたトークンがアプリとデバイスの両方から削除されます。

次の図は、アプリのライフサイクル全体と、アプリの実行中に発生する可能性がある一般的なイベントを示しています。 この図は、アクティビティの起動時、アカウントのサインインとサインアウト、アクティビティの一時停止、再開、停止などのイベントがどのように適合するかを示しています。

共有デバイス アプリのライフサイクル

次のステップ

共有デバイス モードでアプリを実行し、アプリをテストするように Android デバイスを設定します。

Android デバイスの共有デバイス モード