教程:向 Android 应用程序添加共享设备模式支持

在本教程中,Android 开发人员了解如何使用适用于 Android 的 Microsoft 身份验证库 (MSAL) 在 Android 应用程序中添加共享设备模式支持。

本教程的内容:

  • 创建或修改现有的 Android 应用程序项目。
  • 启用和检测共享设备模式
  • 检测单个或多个帐户模式
  • 检测用户开关
  • 启用全局登录和注销

创建或修改现有的 Android 应用程序

若要完成本教程的其余部分,需要创建新的或修改现有的 Android 应用程序。 请参阅 MSAL Android 教程,了解如何将 MSAL 与 Android 应用集成、将用户登录、调用 Microsoft Graph 以及将用户注销(如果尚未了解)。 如果希望使用已完成的代码示例进行学习和测试,请从 GitHub 克隆示例应用程序。 示例能够在单帐户或多帐户模式下工作。

将 MSAL SDK 添加到本地 Maven 存储库

如果你使用的不是示例应用,请在 build.gradle 文件中将 MSAL 库添加为依赖项,如下所示:

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

添加对单帐户模式的支持

使用 Microsoft 身份验证库 (MSAL) SDK 编写的应用程序可以管理单帐户或多帐户。 有关详细信息,请参阅单帐户模式或多帐户模式

适用于应用的 Microsoft 标识平台功能根据应用程序是在单帐户模式还是多帐户模式下运行而异。

共享设备模式应用只能在单帐户模式下工作

重要

仅支持多帐户模式的应用程序无法在共享设备上运行。 如果员工加载不支持单帐户模式的应用,该应用不会在共享设备上运行。

在 MSAL SDK 发布之前编写的应用在多帐户模式下运行,必须更新为支持单帐户模式,才能在共享模式的设备上运行。 同时支持单帐户和多帐户

可将应用构建为支持在个人设备和共享设备上运行。 如果应用目前支持多个帐户,而你想要支持共享设备模式,请添加对单帐户模式的支持。

你可能还希望应用根据其运行的设备类型来更改应用行为。 使用 ISingleAccountPublicClientApplication.isSharedDevice() 确定何时在单帐户模式下运行。

有两个不同的接口表示应用程序所在的设备类型。 从 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;
            ...
        }

根据应用是在共享设备还是个人设备上运行而存在以下差异:

共享模式设备 个人设备
帐户 单帐户 多帐户
登录 全局 全局
注销 全球 每个应用程序都可以控制退出登录是否在应用的本地进行。
支持的帐户类型 仅限工作帐户 支持个人和工作帐户

将应用配置为使用共享设备模式

有关设置配置文件的详细信息,请参阅配置文档

在 MSAL 配置文件中将 "shared_device_mode_supported" 设置为 true

你可能不打算支持多帐户模式。 如果使用的不是共享设备,并且用户可以同时使用多个帐户登录到应用,则可能会出现这种情况。 如果是这样,请将 "account_mode" 设置为 "SINGLE"。 这可以确保你的应用始终获得 ISingleAccountPublicClientApplication,并大大简化你的 MSAL 集成。 "account_mode" 的默认值为 "MULTIPLE",因此,如果使用 "single account" 模式,则必须在配置文件中更改此值。

下面是示例应用的 app>main>res>raw 目录中包括的 auth_config.json 文件的示例:

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

检测共享设备模式

使用共享设备模式,你可以将 Android 设备配置为由多名员工共享,同时为设备提供由 Microsoft Identity 支持的管理。 员工可以登录到其设备并快速访问客户信息。 当他们完成其班次或任务后,只需要单击一次即可注销共享设备上的所有应用,设备就会立即准备就绪,可供下一位员工使用。

使用 isSharedDevice() 确定应用是否正在处于共享设备模式的设备上运行。 你的应用可以使用此标志来确定是否应当相应地修改 UX。

下面是一个代码片段,展示了可以如何使用 isSharedDevice()。 它来自示例应用中的 SingleAccountModeFragment 类:

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

初始化 PublicClientApplication 对象

如果在 MSAL 配置文件中设置了 "account_mode":"SINGLE",则可以放心地将返回的应用程序对象转换为 ISingleAccountPublicCLientApplication

private ISingleAccountPublicClientApplication mSingleAccountApp;

/*Configure your sample app and save state for this activity*/
PublicClientApplication.create(this.getApplicationCOntext(),
  R.raw.auth_config,
  new PublicClientApplication.ApplicationCreatedListener(){
  @Override
  public void onCreated(IPublicClientApplication application){
  mSingleAccountApp = (ISingleAccountPublicClientApplication)application;
  loadAccount();
  }
  @Override
  public void onError(MsalException exception){
  /*Fail to initialize PublicClientApplication */
  }
});

检测单帐户与多帐户模式

如果编写的应用将仅用于共享设备上的一线员工,则建议将应用编写为仅支持单帐户模式。 这包括以任务为中心的大多数应用程序,例如医疗记录应用、发票应用和大多数业务线应用。 这将简化开发,因为不需要包含 SDK 的许多功能。

如果你的应用支持多个帐户和共享设备模式,则必须执行类型检查并强制转换为相应的接口,如下所示。

private IPublicClientApplication mApplication;

        if (mApplication instanceOf IMultipleAccountPublicClientApplication) {
          IMultipleAccountPublicClientApplication multipleAccountApplication = (IMultipleAccountPublicClientApplication) mApplication;
          ...
        } else if (mApplication instanceOf    ISingleAccountPublicClientApplication) {
           ISingleAccountPublicClientApplication singleAccountApplication = (ISingleAccountPublicClientApplication) mApplication;
            ...
        }

获取已登录用户并确定该设备上的用户是否已更改

loadAccount 方法检索已登录用户的帐户。 onAccountChanged 方法确定已登录用户是否已更改,如果已更改,则清除:

private void loadAccount()
{
  mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback())
  {
    @Override
    public void onAccountLoaded(@Nullable IAccount activeAccount)
    {
      if (activeAccount != null)
      {
        signedInUser = activeAccount;
        mSingleAccountApp.acquireTokenSilentAsync(SCOPES,"http://login.microsoftonline.com/common",getAuthSilentCallback());
      }
    }
    @Override
    public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable Iaccount currentAccount)
    {
      if (currentAccount == null)
      {
        //Perform a cleanup task as the signed-in account changed.
        updateSingedOutUI();
      }
    }
    @Override
    public void onError(@NonNull Exception exception)
    {
    }
  }
}

将用户全局登录

以下操作将设备中的用户登录到将 MSAL 与验证器应用结合使用的其他应用:

private void onSignInClicked()
{
  mSingleAccountApp.signIn(getActivity(), SCOPES, null, getAuthInteractiveCallback());
}

将用户全局注销

以下操作将删除已登录的帐户,并从应用中以及处于共享设备模式下的设备中同时清除缓存的令牌:

private void onSignOutClicked()
{
  mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback()
  {
    @Override
    public void onSignOut()
    {
      updateSignedOutUI();
    }
    @Override
    public void onError(@NonNull MsalException exception)
    {
      /*failed to remove account with an exception*/
    }
  });
}

接收广播以检测从其他应用程序启动的全局注销

若要接收帐户更改广播,需要注册广播接收器。 建议通过上下文注册的接收器注册广播接收器。

接收到帐户更改广播后,立即获取已登录用户,并确定设备上的用户是否已更改。 如果检测到更改,则为以前登录的帐户启动数据清理。 建议适当停止任何操作,并进行数据清理。

以下代码片段演示如何注册广播接收器。

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);
}

注册应用程序并设置租户进行测试

在设置应用程序并将设备置于共享设备模式之前,需要在组织租户中注册应用程序。 然后,在 auth_config.json 中提供以下值,以便应用程序能够正常运行。

有关如何执行此操作的信息,请参阅注册应用程序

注意

注册应用时,请使用左侧的快速入门指南,然后选择“Android” 。 这会出现一个页面,要求你为应用提供包名称签名哈希。 这些值对于确保你的应用程序配置正常运行非常重要。 然后,你会收到一个配置对象,可将其用于你要剪切并粘贴到 auth_config.json 文件中的应用。

“配置 Android 应用”页

应选择“为我进行此更改”,然后提供快速入门要求的值。 完成后,Microsoft Entra ID 将生成所需的所有配置文件。

若要进行测试,请在租户中设置以下角色:至少两名员工和一名云设备管理员。 要设置云设备管理员,需要修改组织角色。 从 Microsoft Entra 管理中心,依次选择“身份”>“角色和管理员”>“角色和管理员”>“所有角色”进入“组织角色”,然后选择“云设备管理员”。 添加可将设备置于共享模式的用户。

运行示例应用

该示例应用程序是一个简单应用,它调用你的组织的图形 API。 首次运行时,系统将提示你表明是否同意,因为对于你的员工帐户而言,该应用程序是新的。

应用程序配置信息屏幕

后续步骤

设置 Android 设备以在共享设备模式下运行应用并测试应用。