适用于 Android 的 Intune 应用 SDK - 应用参与功能

Microsoft Intune App SDK for Android 允许将 Intune 应用保护策略 (也称为 APP 或 MAM 策略) 合并到本机 Java/Kotlin Android 应用中。 Intune 托管的应用程序是与 Intune 应用 SDK 集成的应用程序。 当 Intune 主动管理应用时,Intune 管理员可以轻松地将应用保护策略部署到 Intune 托管的应用。

注意

本指南分为几个不同的阶段。 首先查看 规划集成

阶段 7:应用参与功能

阶段目标

  • 了解 Intune 应用 SDK 提供的各种应用参与功能。
  • 集成与应用和用户相关的应用参与功能。
  • 测试这些功能的集成。

什么是“应用参与功能”?

此 SDK 集成过程尝试将开发人员需要编写的特定于应用的代码量降至最低。 通过成功完成 SDK 集成的前一阶段,你的应用现在可以强制实施大多数应用保护策略设置,例如文件加密、复制/粘贴限制、屏幕截图阻止和数据传输限制。

但是,有些设置需要应用特定的代码才能正确强制执行;这些称为应用参与功能。 通常,SDK 没有足够的有关应用程序代码或最终用户方案的上下文来自动强制实施这些设置,因此依赖于开发人员适当地调用 SDK API。

应用参与功能不一定是可选的。 根据应用的现有功能,可能需要这些功能。 有关详细信息 ,请参阅 SDK 集成的关键决策

本指南的上一阶段已经介绍了多个应用参与功能:

本指南的其余部分介绍了剩余的应用参与功能集:

  • 强制实施策略,限制将文件保存到本地或云存储/从本地存储或云存储打开文件。
  • 强制实施限制通知中内容的策略。
  • 强制实施保护备份数据的策略。
  • 如果应用具有自定义屏幕捕获代码) ,则强制实施限制屏幕捕获 (策略。
  • 支持应用保护 CA。
  • 注册 SDK 中的通知。
  • 应用自定义应用程序主题。
  • 使用 Intune 中的受信任证书来确保对本地终结点的信任链。

应用参与功能基础知识

AppPolicy 接口包含许多方法,可通知应用是否允许某些操作。

大多数应用参与功能包括:

  • 确定应用代码中的正确位置,以检查是否允许某个操作。
  • 调用方法 AppPolicy 以根据当前配置的策略检查是否允许某个操作。
  • 根据结果,允许操作完成,或者在操作被阻止时修改应用行为。

若要检索 AppPolicy 实例,请使用 MAMPolicyManager 方法之一,例如 getPolicygetPolicyForIdentity(final String identity)

AppPolicy 中的信息方法

AppPolicy 并非每个方法都与应用参与功能相关联。 某些方法是信息性的,为应用提供当前配置了哪些策略的应用数据,即使 SDK 会自动强制执行这些策略也是如此。 这些方法的存在使你的应用有机会在配置特定策略时提供自定义用户体验。

示例:确定是否阻止屏幕截图

如果应用具有允许用户获取屏幕截图的控件,则如果应用保护策略阻止了屏幕截图,则可能需要禁用或隐藏该控件。

你的应用可以通过调用 MAMPolicyManager.getPolicy(currentActivity).getIsScreenCaptureAllowed()来检查这一点。

用于限制应用与设备或云存储位置之间的数据传输的策略

许多应用允许最终用户将数据保存到本地文件存储或云存储服务或从本地文件存储服务打开数据。 Intune App SDK 允许 IT 管理员通过限制应用将数据保存到和打开数据的位置,防止数据进入和数据泄露。

注意

如果你的应用允许直接从应用保存到个人或云位置, 或者 允许将数据直接打开到应用中,则必须实现此 Intune App SDK 应用参与功能 ,使 IT 管理员能够阻止此保存/打开。

保存到设备或云存储

API getIsSaveToLocationAllowed 可让你的应用知道是否允许根据配置的策略为给定标识保存到特定位置:

MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(
SaveLocation service, String username);

若要确定应用是否应实施 getIsSaveToLocationAllowed 检查,请查看下表,确定应用是否支持数据出口:

service 参数: SaveLocation 枚举值 用例 关联的用户名
ONEDRIVE_FOR_BUSINESS 应用正在将数据保存到 OneDrive。 用于 username 云服务身份验证和Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
SHAREPOINT 应用程序正在将数据保存到 Sharepoint。 用于 username 云服务身份验证和Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
BOX 此应用正在将数据保存到 Box。 用于 username 云服务身份验证和Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
LOCAL 应用将数据保存到设备上的外部存储位置,该位置 不是 应用的专用存储。 外部存储不被视为云服务,因此应始终与用户名参数一 null 起使用。
PHOTO_LIBRARY 应用正在将数据保存到 Android 本地照片存储。 Android 本地照片存储不被视为云服务,因此应始终与用户名参数一 null 起使用。
ACCOUNT_DOCUMENT 应用将数据保存到与应用中的帐户关联的位置,但不是上面指定的特定云位置之一。 *此位置应用于确定是否可以在多标识应用中的帐户之间传递数据。- username用于Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
OTHER 应用将数据保存到上面未指定且不满足 的条件 ACCOUNT_DOCUMENT的位置。 username不会为此位置评估 ,因此应为 null

始终允许放置在专用应用存储中的文件,这些文件要么是应用操作所必需的,要么是临时下载以供显示的文件;无需检查 getIsSaveToLocationAllowed。 执行检查SaveLocation.LOCAL

  1. 保存在专用应用存储外部的文件。
  2. 下载到专用应用存储(无需执行应用操作)的文件 (例如,用户故意选择) 下载到设备。

注意

检查保存策略时, username 应是与要 保存到 (的云服务关联的 UPN/用户名/电子邮件 一定与拥有) 保存文档的帐户相同。

从本地或云存储位置打开数据

通过 getIsOpenFromLocationAllowed API,应用可以根据配置的策略知道给定标识是否允许从特定位置打开:

MAMPolicyManager.getPolicy(currentActivity).getIsOpenFromLocationAllowed(
OpenLocation location, String username);

若要确定应用是否应实现 getIsOpenFromLocationAllowed 检查,请查看下表,确定应用是否支持数据入口:

location 参数: OpenLocation 枚举值 用例 关联的用户名
ONEDRIVE_FOR_BUSINESS 应用正在从 OneDrive 打开数据。 用于 username 云服务身份验证和Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
SHAREPOINT 应用正在从 Sharepoint 打开数据。 用于 username 云服务身份验证和Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
CAMERA 应用正在打开来自相机的数据。 一个 null 值,因为设备相机不是云服务。
LOCAL 应用正在从设备上的外部存储位置( 不是 应用的专用存储)打开数据。 尽管外部存储不是云服务位置,但需要参数 username ,因为它指示所有权。
从本地存储打开文件时,必须始终考虑文件所有者,因为文件所有者的保存策略可能允许或不允许其他标识打开文件:
- 对于标识标记的文件,username 应是文件所有者的标识。
- 对于没有标识标记的文件,username 应为 null
PHOTO_LIBRARY 应用正在从 Android 照片本地存储打开数据。 Android 本地照片存储不被视为云服务,因此应始终与用户名参数一 null 起使用。
ACCOUNT_DOCUMENT 应用从与应用中的帐户关联的位置打开数据,但不是上面指定的特定云位置之一。 *此位置应用于确定是否可以在多标识应用中的帐户之间传递数据。- username用于Microsoft Entra 身份验证的帐户的 。 如果此类用户名不存在或用户名未知,请使用 null
OTHER 应用正在从上面未指定且不满足 的条件 ACCOUNT_DOCUMENT的位置打开数据。 username不会为此位置评估 ,因此应为 null

注意

检查打开策略时, username 应是与 (打开的文件或云服务关联的 UPN/用户名/电子邮件 ,不 一定与) 打开文档的帐户相同。

提示

为方便起见,SDK 提供了 方法, AppPolicy.isOpenFromLocalStorageAllowed 该方法为本地存储中的文件采用 File 参数。 它强制实施策略的术语在功能上与调用AppPolicy.isOpenFromLocationAllowed(OpenLocation.LOCAL, username)相同,只不过它处理从 File分析文件所有者的 username

共享阻止的对话框

SDK 提供了一个对话框,用于通知用户数据传输操作被 MAM 策略阻止。

每当 isSaveToAllowedForLocationisOpenFromAllowedForLocation API 调用导致保存/打开操作被阻止时,都应向用户显示对话框。 对话框显示一条泛型消息,并在关闭时返回到调用 Activity

若要显示对话框,请添加以下代码:

MAMUIHelper.showSharingBlockedDialog(currentActivity)

允许文件共享

如果不允许保存到公共存储位置,则应用仍应允许用户查看文件,方法是将文件下载到 应用专用存储 ,然后使用系统选择器打开这些文件。

限制通知内内容的策略

对于单标识应用,当应用保护策略限制通知时,Intune 应用 SDK 的默认行为将尝试阻止 所有 通知。

SDK 的默认行为是有限的。 SDK 不能自动遵循“阻止组织数据”值,该值仅用于从通知中删除托管内容。 对于多标识应用,SDK 无法确定哪些通知包含托管内容。

如果你的应用显示通知,并且它是多标识和/或希望遵循“阻止组织数据”值,它必须在显示通知之前检查与通知关联的帐户的通知限制策略。

若要确定是否强制实施策略,请进行以下调用:

NotificationRestriction notificationRestriction =
    MAMPolicyManager.getPolicyForIdentity(notificationIdentity).getNotificationRestriction();

返回的 NotificationRestriction 枚举具有以下值:

NotificationRestriction 枚举 预期应用行为
BLOCKED 应用 不得 显示与此策略关联的帐户的任何通知。 对于 单标识 应用,Intune 应用 SDK 将自动阻止所有通知,并且不需要其他代码。
BLOCK_ORG_DATA 应用必须显示不包含组织数据的修改通知。
UNRESTRICTED 应用应显示所有通知。

如果应用未正确调用 getNotificationRestriction,MAM SDK 将尽最大努力自动限制 仅针对单标识应用的通知。

在这种情况下, BLOCK_ORG_DATA 被视为 相同 BLOCKED ,并且根本不显示通知。

若要进行更精细的控制,请检查 的值 getNotificationRestriction 并相应地修改应用通知。

用于保护备份数据的策略

Intune App SDK 可以阻止数据上传到 Android 的内置备份和还原功能。 若要了解有关 Android 中的备份和还原的详细信息,请参阅 Android API 指南 和 Android S /12 中引入的更改: 对备份和还原的更改

应用的自动备份

从 Android M 开始,Android 开始为应用提供 Google Drive 的自动完整备份 ,而不考虑应用的目标 API。

Intune 允许你利用 Android 提供的所有自动备份功能,包括使用特定 Intune 集成指南在 XML 中定义自定义规则的功能,以确保应用数据保护。

在应用的清单中配置备份行为

默认情况下, android:allowBackup 设置为 true ,如 启用和禁用备份中所述。

如果你的应用不需要完整的备份和还原功能,请将 设置为 android:allowBackupfalse在这种情况下,无需采取进一步操作,并且“公司”数据将保留在应用中。

如果应用需要完整的备份和还原功能,请将 设置为 android:allowBackuptrue 并执行以下附加步骤:

  1. 如果你的应用 不使用 自己的自定义 BackupAgent,请使用默认 的 MAMBackupAgent ,以允许自动完整备份符合 Intune 策略。 在应用清单中放置以下内容:

    <application
    ...
      android:fullBackupOnly="true"
      android:backupAgent="com.microsoft.intune.mam.client.app.backup.MAMDefaultBackupAgent"
      ...>
      </application>
    
  2. [可选] 如果实现了可选的自定义 BackupAgent,则需要确保使用 MAMBackupAgentMAMBackupAgentHelper。 请参阅以下部分。 请考虑切换到使用 Intune 的 MAMDefaultBackupAgent,如步骤 1 中所述,它可在 Android M 及更高版本上轻松备份。

  3. 当你决定应用应接收 (未筛选、筛选或无) 的完整备份类型时,需要在应用中将属性 android:fullBackupContent 设置为 true、false 或 XML 资源。

  4. 然后, 必须将 的值 android:fullBackupContent 复制到元数据标记中 com.microsoft.intune.mam.FullBackupContent ,对于支持 API 31 中添加的新 XML 配置格式的应用,则复制到元数据标记中 com.microsoft.intune.mam.DataExtractionRules

    • 示例 1:如果希望应用具有不带排除项的完整备份,则必须将属性和元数据标记设置为 true

      <application
        ...
        android:fullBackupContent="true"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="true" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:value="true" />
      
    • 示例 2:如果希望应用使用其自定义 BackupAgent 并选择退出完全、符合 Intune 策略的自动备份,则必须将属性和元数据标记设置为 false

      <application
        ...
        android:fullBackupContent="false"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="false" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:value="false" />
      
    • 示例 3:如果希望应用根据 XML 文件中定义的自定义规则进行完整备份,请将属性和元数据标记设置为同一 XML 资源:

      <application
        ...
        android:fullBackupContent="@xml/my_full_backup_content_scheme"
        android:dataExtractionRules="@xml/my_data_extraction_rules_scheme"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:resource="@xml/my_full_backup_content_scheme" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:resource="@xml/my_data_extraction_rules_scheme" />
      

键/值备份

“键/值备份”选项可用于所有 API 8+,并将应用数据上传到 Android 备份服务。 每个应用的数据量限制为 5 MB。 如果使用键/值备份,则必须使用 BackupAgentHelperBackupAgent

BackupAgentHelper

BackupAgentHelper 在本机 Android 功能和 Intune MAM 集成方面,BackupAgentHelper 比 BackupAgentHelper 更容易实现,开发人员可以将整个文件和共享首选项分别注册到 FileBackupHelperSharedPreferencesBackupHelper (,) 创建后将其添加到 BackupAgentHelper。 按照以下步骤将 BackupAgentHelper 与 Intune MAM 配合使用:

  1. 若要使用 多标识备份, BackupAgentHelper请遵循 扩展 BackupAgentHelper 的 Android 指南。

  2. 让类扩展 BackupAgentHelper、FileBackupHelper 和 SharedPreferencesBackupHelper 的 MAM。

Android 类 MAM 等效项
BackupAgentHelper MAMBackupAgentHelper
FileBackupHelper MAMFileBackupHelper
SharedPreferencesBackupHelper MAMSharedPreferencesBackupHelper

遵循这些准则将导致成功的多标识备份和还原。

BackupAgent

借助 BackupAgent,可以更明确地了解备份的数据。 由于开发人员对实现负有公平责任,因此需要执行更多步骤来确保 Intune 提供适当的数据保护。 由于大部分工作都由你(开发人员)完成,因此 Intune 集成会稍微增加一些。

集成 MAM:

  1. 仔细阅读 密钥/值备份 的 Android 指南,特别是 扩展 BackupAgent ,以确保 BackupAgent 实现遵循 Android 指南。

  2. 让类扩展 MAMBackupAgent

多标识备份:

  1. 在开始备份之前,请检查 IT 管理员是否确实允许 在多标识方案中备份计划备份的文件或数据缓冲区。 在 isBackupAllowedMAMFileProtectionManagerMAMDataProtectionManager 中使用 来确定这一点。 如果不允许备份文件或数据缓冲区,则不应将其包含在备份中。

  2. 在备份过程中的某个时刻,如果要备份在步骤 1 中签入的文件的标识,则必须使用计划从中提取数据的文件进行调用 backupMAMFileIdentity(BackupDataOutput data, File … files) 。 这会自动创建新的备份实体,并将它们写入到 中 BackupDataOutput 。 还原时将自动使用这些实体。

多标识还原: 数据备份指南指定用于还原应用程序数据的常规算法,并在 扩展 BackupAgent 部分提供代码示例。 若要成功还原多标识,必须遵循此代码示例中提供的常规结构,并特别注意以下事项:

  1. 必须使用 while(data.readNextHeader())* 循环来遍历备份实体。

  2. 如果data.getKey()与在 中onBackup编写的密钥不匹配,则必须调用 data.skipEntityData() 。 如果不执行此步骤,还原可能无法成功。

  3. 在 * 构造中使用 while(data.readNextHeader())备份实体时避免返回 ,因为我们自动写入的实体将丢失。

自定义屏幕捕获限制

如果应用包含绕过 Android 级别FLAG_SECURE限制的Window自定义屏幕捕获功能,则必须在允许完全访问该功能之前检查屏幕截图策略。 例如,如果应用使用自定义呈现引擎将当前视图呈现为 PNG 文件,则必须首先检查 AppPolicy.getIsScreenCaptureAllowed()

注意

如果你的应用不包含任何自定义或第三方屏幕捕获功能,则无需采取任何操作来限制屏幕捕获。 屏幕捕获策略在所有 MAM 集成应用的级别自动强制实施 Window 。 OS 或其他应用在应用中捕获 Window 的任何尝试都将根据需要被阻止。 例如,如果用户尝试通过 Android 的内置屏幕截图或屏幕录制功能捕获应用的屏幕,则捕获将自动受到限制,而无需应用参与。

支持应用保护 CA

应用保护 CA (条件访问) (也称为基于应用的 CA)限制对资源的访问,直到应用程序由 Intune 应用保护策略管理。 Microsoft Entra ID 通过要求应用在授予令牌以访问受 CA 保护的资源之前注册和管理应用来强制实施这一点。

注意

对应用保护 CA 的支持需要版本 1.0.0 (或更高版本的 MSAL 库) 。

使用 MSAL 处理不符合性

为帐户获取令牌时,MSAL 库可能会返回或引发 , MsalIntuneAppProtectionPolicyRequiredException 以指示不符合应用保护策略管理。 可以从异常中提取其他参数以用于修正合规性 (请参阅 MAMComplianceManager) 。 修正成功后,应用可以通过 MSAL 重新尝试获取令牌。

MAMComplianceManager

从 MSAL 收到需要策略的错误时,将使用 MAMComplianceManager 接口。 它包含 [remediateCompliance] 方法,应调用该方法以尝试将应用置于合规状态。 可以按如下所示获取对 MAMComplianceManager 的引用:

MAMComplianceManager mgr = MAMComponents.get(MAMComplianceManager.class);

// make use of mgr

返回 MAMComplianceManager 的实例保证不为 null

package com.microsoft.intune.mam.policy;

public interface MAMComplianceManager {
    void remediateCompliance(String upn, String aadId, String tenantId, String authority, boolean showUX);
}

remediateCompliance()调用 方法以尝试将应用置于管理之下,以满足Microsoft Entra ID 授予所请求令牌的条件。 可以从 MSAL AuthenticationCallback.onError() 方法收到的异常中提取前四个参数, (请参阅下面的代码示例) 。 最后一个参数是一个布尔值,用于控制在合规性尝试期间是否显示 UX。

remediateCompliance 显示一个简单的阻止进度对话框,因此应用不需要在此操作期间显示自定义的 UX。 仅当合规性修正正在进行时,才会显示此对话框;它不会显示最终结果。 你的应用可以为通知注册接收方 COMPLIANCE_STATUS ,以处理合规性修正尝试的成功或失败。 有关详细信息 ,请参阅合规性状态通知

remediateCompliance() 可以在建立合规性过程中启动 MAM 注册。 如果应用已注册注册通知接收方,则可能会收到注册通知。 已注册 MAMServiceAuthenticationCallback 的应用将调用其 acquireToken() 方法来获取注册的令牌。 acquireToken() 将在应用获取自己的令牌之前调用,因此,应用在成功获取令牌后执行的任何簿记或帐户创建任务可能尚未完成。 在这种情况下,回调必须能够获取令牌。

如果无法从 acquireToken()返回令牌,合规性修正尝试将失败。

如果稍后使用所请求资源的有效令牌调用 updateToken ,则会立即使用给定令牌重试符合性修正。

注意

仍可在 中 acquireToken() 获取无提示令牌,因为在收到异常之前 MsalIntuneAppProtectionPolicyRequiredException ,已指导用户安装代理并注册设备。 这会导致中转站在其缓存中具有有效的刷新令牌,从而成功获取请求的令牌。

下面是在 方法中 AuthenticationCallback.onError() 接收需要策略的错误,并调用 MAMComplianceManager 来处理错误的示例。

public void onError(@Nullable MsalException exc) {
    if (exc instanceof MsalIntuneAppProtectionPolicyRequiredException) {

        final MsalIntuneAppProtectionPolicyRequiredException policyRequiredException =
            (MsalIntuneAppProtectionPolicyRequiredException) ex;

        final String upn = policyRequiredException.getAccountUpn();
        final String aadId = policyRequiredException.getAccountUserId();
        final String tenantId = policyRequiredException.getTenantId();
        final String authority = policyRequiredException.getAuthorityURL();

        MAMComplianceManager complianceManager = MAMComponents.get(MAMComplianceManager.class);
        complianceManager.remediateCompliance(upn, aadId, tenantId, authority, showUX);
    }
}

符合性状态通知

如果应用注册了类型的 COMPLIANCE_STATUS通知,则会发送 , MAMComplianceNotification 以便通知应用合规性修正尝试的最终状态。 有关 注册的详细信息,请参阅从 SDK 注册通知

public interface MAMComplianceNotification extends MAMUserNotification {
    MAMCAComplianceStatus getComplianceStatus();
    String getComplianceErrorTitle();
    String getComplianceErrorMessage();
}

方法 getComplianceStatus() 将符合性修正尝试的结果作为 [MAMCAComplianceStatus] 枚举的值返回。

状态代码 解释
UNKNOWN 状态未知。 这可能表示意外的失败原因。 可以在公司门户日志中找到其他信息。
COMPLIANT 合规性修正成功,应用现在符合策略。 应重试 MSAL 令牌获取。
NOT_COMPLIANT 修正符合性尝试失败。 应用不符合要求,在更正错误条件之前,不应重试 MSAL 令牌获取。 其他错误信息随 MAMComplianceNotification 一起发送。
SERVICE_FAILURE 尝试从 Intune 服务检索符合性数据时失败。 可以在公司门户日志中找到其他信息。
NETWORK_FAILURE 连接到 Intune 服务时出错。 恢复网络连接后,应用应再次尝试获取其令牌。
CLIENT_ERROR 由于与客户端相关的某些原因,尝试修正符合性失败。 例如,没有令牌或错误的用户。 其他错误信息随 MAMComplianceNotification 一起发送。
PENDING 尝试修正符合性失败,因为超出时间限制时尚未从服务收到状态响应。 应用应稍后再次尝试获取其令牌。
COMPANY_PORTAL_REQUIRED 必须在设备上安装公司门户,才能成功进行合规性修正。 如果设备上已安装公司门户,则需要重启应用。 在这种情况下,将显示一个对话框,要求用户重启应用。

如果符合性状态为 MAMCAComplianceStatus.COMPLIANT,则应用应为其自己的资源) 重新初始化其原始令牌获取 (。

如果符合性修正尝试失败, getComplianceErrorTitle()getComplianceErrorMessage() 方法将返回本地化字符串,如果应用选择,这些字符串可以显示给最终用户。 大多数错误情况无法由应用修复,因此对于一般情况,最好是帐户创建或登录失败,并允许用户稍后重试。

如果故障持续存在,公司门户日志可能有助于确定原因。 最终用户可以提交日志。 有关详细信息,请参阅 上传和电子邮件日志

下面是使用匿名类注册接收器以实现 MAMNotificationReceiver 接口的示例:

final MAMNotificationReceiverRegistry notificationRegistry = MAMComponents.get(MAMNotificationReceiverRegistry.class);
// create a receiver
final MAMNotificationReceiver receiver = new MAMNotificationReceiver() {
    public boolean onReceive(MAMNotification notification) {
        if (notification.getType() == MAMNotificationType.COMPLIANCE_STATUS) {
            MAMComplianceNotification complianceNotification = (MAMComplianceNotification) notification;
            
            // take appropriate action based on complianceNotification.getComplianceStatus()
            
            // unregister this receiver if no longer needed
            notificationRegistry.unregisterReceiver(this, MAMNotificationType.COMPLIANCE_STATUS);
        }
        return true;
    }
};
// register the receiver
notificationRegistry.registerReceiver(receiver, MAMNotificationType.COMPLIANCE_STATUS);

注意

必须在调用 remediateCompliance() 之前注册通知接收器,以避免可能导致通知错过的争用条件。

声明对应用保护 CA 的支持

应用准备好处理应用 CA 修正后,可以告知Microsoft标识应用已准备好应用 CA。 若要在 MSAL 应用程序中执行此操作,请使用“protapp”的客户端功能生成公共客户端

{
      "client_id" : "[YOUR_CLIENT_ID]",
      "authorization_user_agent" : "DEFAULT",
      "redirect_uri" : "[YOUR_REDIRECT_URI]",
      "multiple_clouds_supported":true,
      "broker_redirect_uri_registered": true,
      "account_mode": "MULTIPLE",
      "client_capabilities": "protapp",
      "authorities" : [
        {
          "type": "AAD",
          "audience": {
            "type": "AzureADandPersonalMicrosoftAccount"
          }
        }
      ]
    }

完成上述操作后,请继续执行下面的 验证应用保护 CA

实现说明

注意

应用的 MAMServiceAuthenticationCallback.acquireToken() 方法应将 false for forceRefresh 标志传递给 acquireTokenSilentAsync()

AcquireTokenSilentParameters acquireTokenSilentParameters =
        builder.withScopes(Arrays.asList(scopes))
               .forceRefresh(false)
               .build();

acquireTokenSilentAsync(acquireTokenSilentParameters);

注意

如果要在修正尝试期间显示自定义阻止 UX,则应将 showUX 参数的 false 传递给 remediateCompliance()。 在调用 remediateCompliance()之前,必须确保先显示 UX 并注册通知侦听器。 这将防止出现争用情况,即如果 remediateCompliance() 很快失败,通知可能会错过。 例如, onCreate() Activity 子类的 或 onMAMCreate() 方法是注册通知侦听器,然后调用 remediateCompliance()的理想位置。 remediateCompliance()的参数可以作为意向附加项传递给 UX。 收到符合性状态通知后,可以显示结果或直接完成活动。

注意

remediateCompliance() 将注册帐户并尝试注册。 获取主令牌后,无需调用 registerAccountForMAM() ,但这样做不会造成伤害。 另一方面,如果应用无法获取其令牌并想要删除用户帐户,则必须调用 unregisterAccountForMAM() 以删除帐户并阻止后台注册重试。

从 SDK 注册通知

Intune 应用 SDK 指南已经讨论了可能需要应用从 SDK 注册通知的几种方案,例如:

本部分介绍 SDK 可以发送的每种类型的通知、应用程序何时以及为何要侦听它,以及如何实现通知接收器。

通知类型

所有 SDK 通知都实现 MAMNotification 接口,该接口具有单个函数 getType(),返回 MAMNotificationType 枚举。

大多数通知都是 MAMUserNotifications,它提供特定于单个标识的信息,可以通过 函数检索 getUserIdentity() 这些信息。

MAMEnrollmentNotificationMAMComplianceNotification 进一步扩展 MAMUserNotification,分别包含尝试向 MAM 服务注册用户/设备的结果和尝试修正应用保护 CA 符合性的结果。

通知类型 通知类 通知原因 适用性 处理提示 线程信息
COMPLIANCE_STATUS MAMComplianceNotification 返回合规性修正尝试的结果。 实现应用保护 CA 的应用必须处理此问题。 - 不确定性
MAM_ENROLLMENT_RESULT MAMEnrollmentNotification 返回注册尝试的结果。 所有应用都会收到此消息。 - 不确定性
MANAGEMENT_REMOVED MAMUserNotification 应用即将变为非托管。 利用 MAMDataProtectionManager 的应用必须处理此问题。 请参阅下面的 MANAGEMENT_REMOVED 从不在 UI 线程上
REFRESH_APP_CONFIG MAMUserNotification 应用配置值可能已更改。 实现应用配置和缓存应用配置数据的应用必须处理此问题。 应用必须使任何缓存的应用配置数据失效并更新。 不确定性
REFRESH_POLICY MAMUserNotification 应用保护策略可能已更改。 缓存应用保护策略的应用必须处理此问题。 应用必须使任何缓存的应用保护策略数据失效并更新。 不确定性
WIPE_USER_DATA MAMUserNotification 擦除即将 (*) 进行。 利用 MAMDataProtectionManager 的应用必须处理此 WIPE_USER_AUXILIARY_DATA 请参阅 选择性擦除 从不在 UI 线程上
WIPE_USER_AUXILIARY_DATA MAMUserNotification 擦除即将 (*) 进行。 只有多标识应用才会收到此消息。
利用 MAMDataProtectionManager 的应用必须处理此 WIPE_USER_DATA
请参阅 选择性擦除 从不在 UI 线程上
WIPE_COMPLETED MAMUserNotification 擦除已完成。 始终可选。 在 或 WIPE_USER_AUXILIARY_DATA之后WIPE_USER_DATA交付。 *如果应用从处理程序WIPE_USER_DATAWIPE_USER_AUXILIARY_DATA或 报告失败,则不会发送此通知。- 从不在 UI 线程上

(*) 擦除可能出于多种原因,例如:

  • 名为 unregisterAccountForMAM 的应用。
  • IT 管理员启动了远程擦除。
  • 不符合管理员所需的条件访问策略。

警告

应用不应同时注册 WIPE_USER_DATAWIPE_USER_AUXILIARY_DATA 通知。

MANAGEMENT_REMOVED

通知 MANAGEMENT_REMOVED 通知应用以前由策略管理的帐户即将变为非托管帐户。 帐户不受管理后,应用将无法再读取该帐户的加密文件、读取使用 MAMDataProtectionManager加密的帐户数据、与加密的剪贴板进行交互,或者无法以其他方式参与托管应用生态系统。

这不需要擦除用户数据或注销用户 (如果需要擦除, WIPE_USER_DATA 则会) 发送通知。 许多应用可能不需要处理此通知,但使用 MAMDataProtectionManager 的应用必须处理此通知。 有关详细信息 ,请参阅数据缓冲区保护

当 SDK 调用应用的 MANAGEMENT_REMOVED 接收器时,以下情况将成立:

  • SDK 已解密以前加密的文件 (但未受保护的数据缓冲区) 属于应用。 sdcard 上公共位置中不直接属于应用的文件 (例如,不会解密) 文档或下载文件夹。

  • 接收方方法创建的新文件或受保护数据缓冲区 (接收方启动后运行的任何其他代码) 不会加密。

  • 应用仍有权访问加密密钥,因此解密数据缓冲区等操作会成功。

应用接收方返回后,将不再有权访问加密密钥。

实现 MAMNotificationReceiver

若要从 SDK 注册通知,应用必须创建 MAMNotificationReceiver 并将其注册到 MAMNotificationReceiverRegistry

若要注册接收方,请在方法中Application.onCreate调用registerReceiver接收方和所需的通知类型:

@Override
public void onCreate() {
  super.onCreate();
  MAMComponents.get(MAMNotificationReceiverRegistry.class)
    .registerReceiver(
      new ToastNotificationReceiver(),
      MAMNotificationType.WIPE_USER_DATA);
}

应用的 MAMNotificationReceiver 实现必须包含 onReceive(MAMNotification notification) 方法。 对于收到的每个通知,将单独调用此方法,并且必须返回 boolean。 通常,此方法应始终返回 true,除非应用程序在响应通知时遇到失败。

与其他类型的 Android 接收器一样,应用程序在处理通知方面具有灵活性:

  • 它可以为不同的通知类型创建不同的 MAMNotificationReceiver 实现, (如下) 所述。 在这种情况下,请确保分别注册每个实现和每个通知类型。
  • 它可以使用单个 MAMNotificationReceiver 实现,其中包含用于响应多个不同通知类型的逻辑。 在这种情况下,必须为它可以响应的每种类型的通知注册它。
  • 它可能会创建多个 MAMNotificationReceiver 实现,每个实现都响应相同的通知类型。 在这种情况下,两者必须注册到相同的通知类型。

提示

可以安全地阻止 , MAMNotificationReceiver.onReceive 因为它的回调未在 UI 线程上运行。

自定义主题

可以向 Intune 应用 SDK 提供自定义主题;此自定义主题将应用于所有 SDK 屏幕和对话框。 如果未提供主题,将使用默认 SDK 主题。

提供自定义主题

若要提供主题,需要在 方法中添加 Application.onMAMCreate 以下代码行:

MAMThemeManager.setAppTheme(R.style.AppTheme);

在上面的示例中,需要将 替换为 R.style.AppTheme 想要应用 SDK 的样式主题。

受信任的根证书管理

如果应用程序需要本地或专用证书颁发机构颁发的 SSL/TLS 证书来提供对内部网站和应用程序的安全访问,则 Intune 应用 SDK 已使用 API 类 MAMTrustedRootCertsManagerMAMCertTrustWebViewClient 添加了对证书信任管理的支持。

注意

MAMCertTrustWebViewClient 支持 Android 10 或更高版本。

受信任的根证书管理支持:

  • SSLContext
  • SSLSocketFactory
  • TrustManager
  • WebView

要求

注意

受信任的根证书管理可以独立于Microsoft隧道 VPN 网关使用,但你必须Microsoft MAM Tunnel 许可才能使用。

使用 Intune 中的受信任的根证书建立信任定位点

受信任的根证书管理允许应用将 Intune 中的受信任的根证书与来自设备的证书结合使用。

如果设备的受信任根证书存储区不包含所需的受信任的根证书,则 MAMTrustEdRootCertsManagerMAMCertTrustWebViewClient 使用通过应用配置策略提供的 Intune 受信任的根证书作为回退选项。 这样,应用可以使用设备和 Intune 证书来验证与受信任源的安全连接和通信。

为了增强其网络安全设置,应用可以使用网络安全配置 XML 文件。 受信任的根证书管理通过验证应用的网络安全配置 XML 是否具有以下任一功能来遵守此额外的安全性:

  • 具有其他 CA(例如自签名证书)的自定义信任定位点。
  • 用于限制受信任 CA 的特定于域的规则。
  • 特定域的证书的固定集。

注意

有关 Android 网络安全配置的详细信息,请参阅: 网络安全配置

如果其中任何一项适用于正在检查信任的域,则受信任的根证书管理将跳过此域的自定义信任检查,只允许平台的默认信任管理器执行检查。

类 MAMTrustedRootCertsManager

此类提供以下 API:

  • createSSLContext(String identity, String protocol):创建一个 SSLContext 对象,该对象对指定的标识和指定的 SSL/TLS 协议使用受信任的根证书。 此类返回 SSLContext 的对象已使用 X509TrustManager 来自设备和 MAM 服务的组合受信任的根证书的对象正确初始化。
  • createSSLSocketFactory(String identity, String protocol):创建一个 SSLSocketFactory 对象,该对象对指定的标识和指定的 SSL/TLS 协议使用受信任的根证书。 返回 SSLSocketFactory 的对象是从此类中的同一 SSLContext 对象引用的。
  • createX509TrustManagers(String identity):创建一个对象数组 X509TrustManager ,这些对象使用来自设备和 MAM 服务的组合受信任的根证书作为指定标识。

注意

参数 identity 应是运行应用程序(例如 UPN)的特定用户的字符串标识符。 如果用户标识符事先未知,则可以传入 null 值,并且 MAM 将尝试从调用这些 API 的线程或进程中发现正确的标识。 必须在进程或线程上正确设置标识,MAM 才能发现标识。 若要详细了解如何在进程或线程上设置活动标识,请访问: 阶段 5:多标识

注意

protocol如果未提供 参数,则使用平台上支持的最高 SSL/TLS 协议。

下面是使用此类的一些示例。

使用 HttpsUrlConnection 的示例
// Create an SSL socket factory using supplying the optional parameters identity and protocol
SSLSocketFactory sslSocketFactory = MAMTrustedRootCertsManager.createSSLSocketFactory(identity, "TLSv1.3");

// Create a URL object for the desired endpoint
URL url = new URL("https://example.com");

// Open a connection using the URL object
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();

// Set the SSL socket factory for the connection
httpsURLConnection.setSSLSocketFactory(sslSocketFactory);

// Perform any other configuration or operations on the connection as needed
...
使用 OkHttpClient 的示例
// Get the TrustManager instances for an identity from the SDK
TrustManager[] trustManagers = MAMTrustedRootCertsManager.createX509TrustManagers(identity);

// Get SSLContext from the platform
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");

// Initialize the SSLContext with the trust managers from the Intune App SDK
sslContext.init(null, trustManagers, null);  

// Create an OkHttpClient.Builder object
OkHttpClient.Builder builder = new OkHttpClient.Builder();

// Set the SSLSocketFactory and the trust managers from the SDK
builder.sslSocketFactory(sslContext.socketFactory, trustManagers[0] as X509TrustManager).build();

// Build an OkHttpClient object from the builder
OkHttpClient okHttpClient = builder.build();

// Create a Request object for the desired endpoint
Request request = new Request.Builder().url("https://example.com").build();

// Execute the request using the OkHttpClient object and get a Response object
Response response = okHttpClient.newCall(request).execute();

// Perform any other operations on the response as needed
...

类 MAMCertTrustWebViewClient

此类提供 Android 类的自定义实现,该类android.webkit.WebViewClient提供了一种处理 中的 WebViewSSL 错误android.net.http.SslError.SSL_UNTRUSTED的方法。 在处理错误时, 类使用在 Intune 中配置并从 MAM 服务接收的受信任根证书来检查中生成 SSL 错误的目标 URL 中的 WebView主机的可信度。 如果自定义实现未处理 SSL 错误,则将调用从超类继承的默认行为。 使用此类时,应创建它的实例,然后调用 WebView.setWebViewClient(WebViewClient) 以将其注册到 WebView 实例。

下面是使用此类的示例。

使用 WebView 的示例
// Get the MAM implementation of WebViewClient from the Intune App SDK
MAMCertTrustWebViewClient mamCertTrustWebViewClient = new MAMCertTrustWebViewClient();

// Set the MAM WebViewClient from the SDK as the current handler on the instance of WebView
webView.setWebViewClient(mamCertTrustWebViewClient);

// Perform any other operations on WebView
...

退出条件

若要便于测试,请参阅 使用更改策略进行快速 测试。

验证保存到/从限制打开

如果未实施 策略来限制应用与设备或云存储位置之间的数据传输,请跳过。

重新熟悉应用可以将数据保存到云服务或本地数据以及从云服务或本地数据打开数据的每一种方案。

为简单起见,这些测试假定你的应用仅支持从应用中的单个位置保存到 OneDrive for Business 以及从 OneDrive for Business 打开数据。 但是,你必须验证每个组合:针对应用允许保存数据的每个位置的每个受支持的保存位置,以及针对应用允许打开数据的每个位置的每个受支持的打开位置。

对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户登录。 此外:

  • 将托管帐户的策略设置为:
    • “将组织数据发送到其他应用”到“策略托管应用”。
    • “从其他应用接收数据”到“策略托管应用”。
应用场景 前提 条件 步骤
保存到,完全允许 将“保存组织数据的副本”策略设置为“允许” - 导航到应用可将数据保存到 OneDrive for Business 的位置。
- 尝试将文档保存到 OneDrive for Business,并将其保存到登录到应用的同一托管帐户。
- 确认是否允许保存。
保存到,豁免 - 将“保存组织数据的副本”策略设置为“阻止”
- “允许用户将副本保存到所选服务”策略设置为仅“OneDrive for Business”
- 导航到应用可将数据保存到 OneDrive for Business 的位置。
- 尝试将文档保存到 OneDrive for Business,并将其保存到登录到应用的同一托管帐户。
- 确认是否允许保存。
- 如果应用允许,请尝试将文件保存到其他云存储位置,并确认它已被阻止。
保存到,已阻止 “保存组织数据的副本”策略设置为“阻止” - 导航到应用可将数据保存到 OneDrive for Business 的位置。
- 尝试将文档保存到 OneDrive for Business,并将其保存到登录到应用的同一托管帐户。
- 确认已阻止保存。
- 如果应用允许,请尝试将文件保存到其他云存储位置,并确认它已被阻止。
打开自,完全允许 “将数据打开到组织文档中”策略设置为“允许” - 导航到应用可从 OneDrive for Business 打开数据的位置。
- 尝试从登录到应用存储的同一托管帐户从 OneDrive for Business 打开文档。
- 确认是否允许打开。
打开自,已免除 - “将数据打开到组织文档中”策略设置为“阻止”
- “允许用户从所选服务打开数据”策略设置为“OneDrive for Business”
- 导航到应用可从 OneDrive for Business 打开数据的位置。
- 尝试从登录到应用存储的同一托管帐户从 OneDrive for Business 打开文档。
- 确认是否允许打开。
- 如果应用允许,请尝试从其他云存储位置打开另一个文件,并确认它已被阻止。
打开自,已阻止 设置为“阻止”的“向组织文档打开数据”策略 - 导航到应用可从 OneDrive for Business 打开数据的位置。
- 尝试从登录到应用存储的同一托管帐户从 OneDrive for Business 打开文档。
- 确认打开已阻止。
- 如果应用允许,请尝试从其他云存储位置打开另一个文件,并确认它已被阻止。

验证通知限制

如果未实现 限制通知内内容的策略,请跳过。

就应用保护策略而言,应用程序可能会触发三种不同类型的通知:

  1. 不包含任何帐户数据的通知。
  2. 包含属于托管帐户的数据的通知。
  3. 包含属于非托管帐户的数据的通知。

如果应用程序是单一标识,则只有前 2 个标识相关,因为如果唯一帐户不受管理,则不会应用任何保护。

可以通过触发配置不同策略值的所有三种类型的通知来验证通知限制。

对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户登录。 如果你的应用是多标识的,则还要使用非托管帐户登录到你的应用。

应用场景 前提 条件 步骤
阻止完整内容 “组织数据通知”策略设置为“阻止” - 触发应用以触发没有帐户数据的通知。
- 确认此通知不显示任何内容。
- 触发应用以使用托管帐户的数据触发通知。
- 确认此通知不显示任何内容。
- 触发应用以使用非托管帐户的数据触发通知。
- 确认此通知不显示任何内容。
部分内容被阻止 “组织数据通知”策略设置为“阻止组织数据” - 触发应用以触发没有帐户数据的通知。
- 确认此通知显示其完整内容。
- 触发应用以使用托管帐户的数据触发通知。
- 确认此通知会修订托管帐户的内容。
- 触发应用以使用非托管帐户的数据触发通知。
- 确认此通知显示其完整内容。
未阻止任何内容 “组织数据通知”策略设置为“允许”

验证数据备份和还原

如果未实现 用于保护备份数据的策略,请跳过。

重新熟悉应用已配置备份的内容 (文件和/或键值对) 。 应验证 是否只有 预期的内容是还原的一部分。 还原中的额外内容可能会导致数据泄漏。

对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户登录。 如果你的应用是多标识的,则还要使用非托管帐户登录到你的应用。

按照 Android 的官方说明测试备份。 这些说明与自动备份和键/值备份不同,因此请密切遵循。

根据策略验证自定义屏幕捕获

如果未实现 自定义屏幕捕获限制,请跳过。

如果应用程序具有绕过 Android Window级别 FLAG_SECURE的功能,请验证此功能是否被应用保护策略屏幕捕获限制阻止。

对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户登录。

应用场景 前提 条件 步骤
屏幕捕获已阻止 “屏幕捕获和 Google 助手”策略设置为“阻止” - 导航到应用中利用自定义FLAG_SECURE代码的位置。
- 尝试利用该功能。
- 确认该功能被阻止。
允许的屏幕捕获 将“屏幕捕获和 Google 助手”策略设置为“允许” - 导航到应用中利用自定义FLAG_SECURE代码的位置。
- 尝试利用该功能。
- 确认是否允许该功能。

验证应用保护 CA

如果未实现 支持应用保护 CA,请跳过。

除了创建应用保护策略并将其分配给应用和测试帐户的典型验证步骤外,还必须创建应用保护条件访问策略并将其分配给测试帐户。 有关详细信息 ,请参阅使用 Intune 设置基于应用的条件访问策略

测试步骤:

  1. 在开始此测试之前,请卸载 Microsoft Authenticator 和 Intune 公司门户。
  2. 安装应用。
  3. 使用应用保护策略和基于应用的 CA 策略的目标测试帐户登录到应用。
  4. 确认应用提示你安装公司门户。
  5. 再次登录。
  6. 确认应用提示你注册设备。 按照提示操作。 如果应用未在此处提示注册,请首先确认测试设备已卸载其他启用了 SDK 的应用、公司门户和 Authenticator。 如果这仍然没有提示,请重新访问上面的实现说明。
  7. 确认可以在注册后访问所有应用数据。

验证通知接收器

如果未从 SDK 实现注册通知,请跳过。

验证步骤取决于应用注册的通知类型。 对于所有类型的通知,请添加日志记录,以确保正确调用接收方。

MAM_ENROLLMENT_RESULT 只需先使用具有应用保护策略的帐户登录到应用程序即可触发。

REFRESH_APP_CONFIGREFRESH_POLICY 可以通过更新针对测试帐户的相应应用配置策略和应用保护策略并等待 SDK 接收更新的策略来触发。

提示

请参阅 使用更改策略快速测试 以加快此过程。

MANAGEMENT_REMOVEDWIPE_USER_DATAWIPE_USER_AUXILIARY_DATAWIPE_COMPLETED 通知都可以通过从 Intune Microsoft 发出选择性擦除 来触发。

验证自定义主题

如果未实现 自定义主题,请跳过。

可以通过检查 SDK 对话框上的颜色来验证自定义主题支持。 要检查的最简单对话框是 MAM PIN 屏幕。

前提 条件:

  • 将托管帐户的策略设置为:
    • 将“用于访问的 PIN”更改为“必需”。
  • 安装应用和 Intune 公司门户。

测试步骤:

  1. 启动应用程序并使用测试帐户登录。
  2. 确认“MAM PIN”屏幕出现,并根据提供给 SDK 的自定义主题设置主题。

后续步骤

如果你按顺序遵循了本指南并已完成上述所有 退出条件恭喜,你的应用现在已与 Intune 应用 SDK 完全集成,并且可以强制实施应用保护策略! 如果跳过了前面的应用参与部分之一 :阶段 5:多标识阶段 6:应用配置,并且不确定应用是否应支持这些功能,请重新访问 SDK 集成的关键决策

应用保护现在是应用的核心方案。 继续开发应用时,请继续参考本指南和 附录