适用于 Android 的 Microsoft Intune App SDK 允许将 Intune 应用保护策略 (也称为 MAM 策略) 合并到本机 Java/Kotlin Android 应用中。 Intune 托管的应用程序是与 Intune 应用 SDK 集成的应用程序。 当 Intune 主动管理应用时,Intune 管理员可以轻松地将应用保护策略部署到 Intune 管理的应用。
注意
本指南分为几个不同的阶段。 首先查看 第 1 阶段:规划集成。
阶段 5:多重身份
阶段目标
- 确定应用程序是否需要多标识支持。
- 了解 Intune 应用 SDK 如何感知标识。
- 重构应用程序以提高标识感知。
- 添加代码,通知 SDK 整个应用程序中的活动和更改标识。
- 全面测试托管标识和非托管标识的应用保护策略强制。
标识术语
术语“用户”、“帐户”和“标识”经常互换使用。 本指南尝试按以下方式进行区分:
- 用户:使用软件产品的人类。 进一步区分为最终用户、使用 Android 应用的人类和管理员 / 用户 / IT 管理员 / IT 专业人员,即使用 Microsoft Intune 管理中心的人类。
- 帐户:属于唯一标识用户实体的组织的软件记录。 人类用户可以有多个帐户。
- 标识:Intune 应用 SDK 用于唯一标识帐户的数据集。
背景
默认情况下,Intune 应用 SDK 将策略应用于整个应用程序。 注册具有目标应用保护策略的帐户后,SDK 会将每个文件和每个活动与该帐户的标识相关联,并将普遍应用该帐户的目标策略。
对于许多开发人员来说,这是其应用程序所需的应用保护行为。 这些应用程序被视为 单一身份。 通过完成前面的阶段,您的应用程序已成功集成为单一身份,并且可以强制实施所有基本策略。 打算保持单一标识的应用可以跳过此部分,并转到阶段 6:应用程序配置。
Intune 应用 SDK 可以选择在每个标识级别强制实施策略。 如果你的应用程序已支持同时登录的多个帐户,并且你希望通过应用保护策略保留这种多帐户支持,则你的应用程序将被视为 多标识。
提示
如果不清楚应用程序应支持单一身份还是多身份保护,请重新访问 我的应用程序是单身份还是多身份?
警告
支持多重身份比其他应用保护功能要复杂得多。 多身份集成不当可能会导致数据泄露和其他安全问题。 在进入下一阶段之前,请仔细查看本节并计划充足的测试时间。
SDK 的“标识”
当 SDK 集成应用程序使用 registerAccountForMAM 注册帐户时,SDK 会将提供的所有参数 (upn、aadId、tenantId 和 authority) 保存为标识。 但是,大多数 SDK 的标识 API 使用提供的 OID (也称为 Microsoft Entra ID 或 AAD ID) 作为标识符。 MAM SDK API 将返回 OID 字符串作为标识,并且需要 OID 字符串参数作为标识。 某些方法可能还采用或返回 UPN 字符串,在这种情况下,UPN 仅用于信息提供的目的。
标识参数不区分大小写。 对 SDK 的标识请求可能不会返回注册或设置标识时使用的相同大小写。
警告
对于使用采用或返回 UPN 字符串的弃用方法的应用,应用必须确保传递到各种 API 调用的标识 UPN 字符串是一致的。 传递不一致的 UPN 字符串可能会导致数据泄漏。
托管标识与非托管标识
如 注册应用保护策略中所述,应用程序负责在用户登录时通知 SDK。 登录时,用户的帐户可能是也可能不是应用保护策略的目标。 如果帐户是应用保护策略的目标,则 SDK 将其视为托管帐户;否则,它是非托管的。
SDK 将对其视为托管的标识强制实施策略。 SDK 不会对其视为非托管的标识强制实施策略。
目前,Intune 应用 SDK 仅支持每个设备的单个托管标识。 一旦任何 SDK 集成的应用程序注册了托管标识,所有后续注册的标识(即使它们当前是应用保护策略的目标)都将被视为非托管标识。
如果已在设备上注册托管标识,并且你的应用注册了另一个同样针对应用保护策略的标识,则 SDK 将返回 MAMEnrollmentManager.Result.WRONG_USER 并提示最终用户修正选项。
有关更多详细信息,请参阅 注册来自 SDK 的通知 。
注意
注册时未作为应用保护策略目标的帐户将被视为非托管帐户。 即使帐户未获得应用保护策略的许可或目标,SDK 也将定期检查此帐户是否在以后获得许可并成为目标帐户。 如果未注册任何其他托管标识,则在与策略定位后,SDK 会开始将此标识视为托管标识。 用户无需注销并重新登录到此帐户即可进行此更改。
活动标识
应用程序必须始终使 SDK 了解当前使用的标识(也称为活动标识)。 如果活动标识是托管的,则 SDK 将应用保护。 如果未管理活动标识,则 SDK 将不会应用保护。
由于 SDK 没有特定于应用程序的知识,因此它必须信任应用程序才能共享正确的活动标识。
如果应用程序在实际使用托管标识时错误地告知 SDK 非托管标识处于活动状态,则 SDK 将不会应用保护。 这可能会导致数据泄露,使用户的数据面临风险。
如果应用程序在实际使用非托管标识时错误地告知 SDK 托管标识处于活动状态,则 SDK 将不恰当地应用保护。 这不是数据泄露,但这可能会不必要地限制非托管用户,并使非托管用户的数据面临删除的风险。
如果应用程序显示任何用户的数据,则必须仅显示属于活动标识的数据。 如果应用程序当前不知道谁拥有显示的数据,则可能需要在开始集成多标识支持之前重构应用程序,以提高标识感知。
按标识组织应用数据
每当应用程序写入新文件时,SDK 都会 (也称为“标记”) 基于当前活动线程和进程标识将标识与该文件相关联。 或者,应用可以直接调用 SDK 以手动标记具有特定标识的文件 (有关详细信息) 请参阅编写受保护的Files。 SDK 将此标记的文件标识用于文件加密和选择性擦除。
如果托管标识以加密策略为目标,则仅加密带有托管标识标记的文件。
如果管理员操作或配置的策略请求擦除托管数据,则仅删除带有托管标识标记的文件。
SDK 不能将多个标识与单个文件相关联。 如果应用将属于多个用户的数据存储在同一文件中,则 SDK 的默认行为将导致对这些数据保护不足或过度保护。 强烈建议你按标识组织应用的数据。
如果应用绝对必须在同一文件中存储属于不同标识的数据,则 SDK 提供了在文件中标记数据子集的功能。 有关详细信息,请参阅 数据缓冲区保护 。
实现多重身份
要声明对应用的多重身份支持,请首先在 AndroidManifest.xml 中放置以下元数据。
<meta-data
android:name="com.microsoft.intune.mam.MAMMultiIdentity"
android:value="true" />
设置活动标识
应用程序可以在以下级别上按优先级降序设置活动标识:
- 线程级
-
Context(一般)Activity级别 - 进程级别
线程级别的标识集取代了该 Context 级别的标识集,后者取代了进程级别的标识集。
上 Context 设置的标识仅用于适当的关联方案。
例如,文件 IO 操作没有关联 Context的 .
最常见的情况下,应用会 Context 在 Activity.
请考虑在 中Activity.onCreate设置Context标识。
除非标识Activity设置为同一标识,否则应用不得显示标识的数据。
通常,仅当应用在所有线程上一次仅使用一个标识时,进程级标识才有用。
对于支持多个帐户的应用来说,这不是典型行为。
强烈建议您隔离帐户数据并在线程或 Context 级别上设置活动标识。
如果应用使用上下文来 Application 获取系统服务,请确保已设置线程或进程标识,或者已在应用的 Application 上下文上设置 UI 标识。
如果应用使用 Service 上下文来启动意图、使用内容解析器或利用其他系统服务,请务必在上下文上 Service 设置标识。
同样,如果您的应用使用上下文来JobService执行这些操作,请务必根据您的实现的要求JobService在上下文或线程上JobService设置标识。
例如,如果处理 JobService 单个标识的作业,请考虑在上下文上 JobService 设置标识。
如果处理多个标识的作业,请 JobService 考虑在线程级别设置标识。
警告
使用“的 WorkManager 应用在设置标识时应特别小心。
具体而言,这些应用应避免在 Context 传入构造函数上 Worker 设置标识。
此 Context 实例可以同时在多个 Worker 实例之间共享。
为了避免未定义的行为,应用应改为根据实现的要求Worker设置线程标识Worker.doWork()。
注意
由于用于 CLIPBOARD_SERVICE UI 操作,因此 SDK 使用前台活动 ClipboardManager 的 UI 标识进行操作。
MAMPolicyManager 中的以下方法可用于设置活动标识和检索以前设置的标识值。
public static void setUIPolicyIdentityOID(final Context context, final String oid,
final MAMSetUIIdentityCallback mamSetUIIdentityCallback, final EnumSet<IdentitySwitchOption> options);
public static String getUIPolicyIdentityOID(final Context context);
public static MAMIdentitySwitchResult setProcessIdentityOID(final String oid);
public static String getProcessIdentityOID();
public static MAMIdentitySwitchResult setCurrentThreadIdentityOID(final String oid);
public static String getCurrentThreadIdentityOID();
/**
* Get the current app policy. This does NOT take the UI (Context) identity into account.
* If the current operation has any context (e.g. an Activity) associated with it, use the overload below.
*/
public static AppPolicy getCurrentThreadPolicy();
/**
* Get the current app policy. This DOES take the UI (Context) identity into account.
* If the current operation has any context (e.g. an Activity) associated with it, use this function.
*/
public static AppPolicy getPolicy(final Context context);
public static AppPolicy getPolicyForIdentityOID(final String oid);
public static boolean getIsIdentityOIDManaged(final String oid);
为方便起见,还可以直接通过 MAMActivity 中的方法设置活动的标识,而不是调用 MAMPolicyManager.setUIPolicyIdentityOID。
使用以下方法执行此操作:
public final void switchMAMIdentityOID(final String newIdentityOid, final EnumSet<IdentitySwitchOption> options);
注意
如果您的应用尚未在清单中声明多标识支持,则调用这些方法来设置标识将不会执行任何操作,如果它们返回 MAMIdentitySwitchResult,则始终返回 FAILED。
常见的身份切换陷阱
对于对
startActivity,Intune 应用 SDK 假定该Context级别的活动标识与提供的Intent参数相关联。 强烈建议使用 'Activitys 上下文(而不是Application's)来设置Context关卡标识。建议在活动
onCreate方法期间设置Context标识。 但是,请务必同时涵盖其他入口点,例如onNewIntent. 否则,当重复使用同一活动来显示托管标识和非托管标识的数据时,可能会错误地应用策略,从而导致公司数据不受保护或个人数据受不当限制。
身份切换结果
用于通过 MAMIdentitySwitchResult 设置标识报告返回结果值的所有方法。 可以返回四个值:
| 返回值 | 应用场景 |
|---|---|
SUCCEEDED |
标识更改成功。 |
NOT_ALLOWED |
不允许更改标识。 如果在当前线程上设置了不同的标识时尝试设置 UI (Context) 标识,则会发生这种情况。 |
CANCELLED |
用户取消标识更改,通常是通过按 PIN 或身份验证提示上的后退按钮。 |
FAILED |
标识更改因不明原因失败。 |
应用在显示或使用托管帐户的数据之前应验证 MAMIdentitySwitchResultSUCCEEDED。
大多数设置活动身份的方法都会同步返回 MAMIdentitySwitchResult 。
在通过 setUIPolicyIdentityOID 设置Context标识的情况下,将异步报告结果。
应用可以实现 MAMSetUIIdentityCallback 来接收此结果,或者可以为回调对象传递 null。
如果在上一次调用ContextsetUIPolicyIdentityOID的结果尚未传递时进行setUIPolicyIdentityOID调用,则新回调将取代旧回调,并且原始回调永远不会收到结果。
警告
如果提供给 ContextsetUIPolicyIdentityOIDActivity是一个 ,则在执行管理员配置的条件启动检查后,SDK 才知道标识更改是否成功。
这可能需要用户输入 PIN 或公司凭据。
目前,对于启用多标识的应用,进程和线程标识切换将始终成功。 SDK 保留将来添加失败条件的权利。
如果 UI 标识切换可能因参数无效而失败,这会与线程标识冲突,或者用户取消条件启动要求 (例如,按 PIN 屏幕上的后退按钮) 。
活动上 UI 标识切换失败的默认行为是完成活动。
要更改此行为并接收有关活动身份更改尝试的通知,可以重写 中的某个方法 MAMActivity。
public void onSwitchMAMIdentityComplete(final MAMIdentitySwitchResult result);
如果您确实替代 onSwitchMAMIdentityComplete (或调用 super 方法) ,则 必须 确保在身份切换失败后不会显示托管帐户的数据。
注意
切换标识可能需要重新创建活动。
在这种情况下, onSwitchMAMIdentityComplete 回调将传递到活动的新实例。
标识、意图和 IdentitySwitchOptions
除了使用活动身份自动标记新文件外,SDK 还使用活动身份标记 意向 。 默认情况下,SDK 将检查传入意向的身份,并将其与活动身份进行比较。 如果这些标识不匹配,SDK 通常会 (*) 请求标识切换, (参阅下面的隐 式标识更改, 以获取更多详细信息) 。
SDK 还会存储此传入意向标识以供以后使用。 当应用显式更改 UI 标识时,SDK 会将应用尝试切换到的标识与最新的传入意向标识进行比较。 如果这些标识不匹配,SDK 通常会 (*) 身份切换失败。
SDK 执行此检查是因为它假定应用仍在显示来自属于意图上标记的标识的意向的内容。 此假设可防止应用在显示托管数据时无意中关闭保护;但是,此假设对于应用的实际行为可能不正确。
可选的 IdentitySwitchOption 枚举可以传递给 setUIPolicyIdentityOID 和 switchMAMIdentityOID API 来修改 SDK 的默认行为。
IGNORE_INTENT:在 UI 层请求身份切换时,此选项会通知 SDK 跳过将请求的身份参数与最近存储的意向身份进行比较。 当应用不再显示属于该标识的内容,并且 SDK 不应阻止此标识切换时,这非常有用。 例如:- 应用是文档查看器。 它可以呈现从其他应用传入的文档。 它还包含用户可以切换帐户的功能。 每当用户使用此帐户切换功能时,应用程序都会导航到包含该帐户最近文档的特定于帐户的登录页面。
- 应用接收到显示文档的意向。 此意向使用托管标识进行标记。
- 应用将切换到托管标识并显示此文档,并正确应用了保护。
- 用户使用帐户切换器更改为其个人帐户。
应用必须在步骤 4 中更改 UI 标识。 在这种情况下,由于应用的行为是离开托管帐号的数据 (意向) 中的文档,因此应
IGNORE_INTENT在身份切换调用中使用该应用。 这可避免 SDK 不恰当地导致此调用失败。DATA_FROM_INTENT:在 UI 层请求身份切换时,此选项会通知 SDK: 身份切换成功后,将继续显示来自最近存储的意向身份的数据。 因此,SDK 将根据之前的意向标识全面评估接收策略,以确定是否允许显示它。 例如:- 应用是文档查看器。 它可以呈现从其他应用传入的文档。 它还包含用户可以切换帐户的功能。 与前面的示例不同的是,每当用户使用此帐户切换功能时,应用程序都会导航到显示 所有帐户最近文档的共享页面。
- 应用接收到显示文档的意向。 此意向使用托管标识进行标记。
- 应用将切换到托管标识并显示此文档,并正确应用了保护。
- 用户使用帐户切换器更改为其个人帐户。
应用必须在步骤 4 中更改 UI 标识。 在这种情况下,由于应用的行为是在意向) 中继续显示托管标识的数据 (文档预览,因此它应在
DATA_FROM_INTENT标识切换调用中使用。 这会通知 SDK 检查配置的应用保护策略,以确定是否适合继续显示数据。
(*) SDK 的默认行为确实包含特殊大小写,如果意图来自同一应用内部或系统启动程序,则会跳过此数据入口检查。
清除活动标识
应用程序可能具有与帐户无关的方案。 应用程序可能还具有不需要任何登录的本地非托管方案方案。 在这两种情况下,应用可能不希望 SDK 强制实施托管标识的策略,但你可能没有要切换到的显式标识。
您可以通过调用任何将标识 OID 参数设置为 null的设置标识方法来清除活动标识。
清除一个级别的标识将导致 SDK 根据优先顺序在其他级别查找活动标识。
或者,可以将空字符串作为标识 OID 参数传递,这会将标识设置为一个特殊的空值,该值被视为非托管标识。 将活动标识设置为空字符串会告知 SDK 不强制实施 任何 应用保护策略。
隐式标识更改
上一部分介绍了应用可以在线程、上下文和进程级别显式设置活动标识的不同方法。 但是,也可以更改应用中的活动标识,而无需应用调用任何这些方法。 本部分介绍应用如何侦听和响应这些隐式标识更改。
侦听这些隐式标识更改是可选的,但建议这样做。 如果不提供这些隐式标识更改通知,SDK 将永远不会更改活动标识。
警告
如果应用选择不侦听隐式标识更改,请格外小心,不要假设处于活动状态的标识。
如有疑问,请使用 getCurrentThreadIdentityOID、 getUIPolicyIdentityOID和 getProcessIdentityOID 方法确认活动标识。
隐式标识更改的来源
来自其他 Intune 托管应用的数据入口可以更改线程和上下文级别的活动标识。
如果活动是从另一个 MAM 应用发送的 启动
Intent的,则将根据发送时其他应用Intent中的活动标识设置该活动的标识。- 例如,当用户选择文档附件时,将从 Microsoft Outlook 的意向启动查看 Word 文档的活动。 Office 的文档查看器活动的标识将切换为 Outlook 中的标识。
对于服务,线程标识将在 OR
onBind调用持续时间onStart内以类似方式设置。 调用Binder返回自onBind也将临时设置线程标识。调用 将
ContentProvider以类似方式设置其持续时间内的线程标识。
用户与活动的交互可以更改上下文级别上的活动标识。 例如:
- 用户在此期间
Resume取消授权提示将导致隐式切换到空标识。
- 用户在此期间
处理隐式标识更改
应用可以选择侦听这些隐式标识更改并对其作出响应。 例如,在添加的帐户可用之前,应用程序可能需要多个步骤,例如电子邮件应用设置新的收件箱。 在看到尝试的标识切换到此不完整帐户的标识后,应用的处理程序可能会在接受标识切换之前将用户重定向到帐户设置活动。 或者,应用的处理程序可以显示错误对话框并阻止标识切换。
应用可以在 MAMIdentityRequirementListener 接口上 Service 实现 MAMIdentityRequirementListener 接口,或 ContextProvider 用于应用于此线程的标识更改。 你的实施必须替代:
public abstract void onMAMIdentitySwitchRequired(String upn, String oid,
AppIdentitySwitchResultCallback callback);
你的应用可以在应用于此活动的标识更改上Activity实现 MAMActivityIdentityRequirementListener 接口。
你的实施必须替代:
public abstract void onMAMIdentitySwitchRequired(String upn, String oid,
AppIdentitySwitchReason reason,
AppIdentitySwitchResultCallback callback);
枚举参数描述 AppIdentitySwitchReason 隐式标识开关的源。
| 枚举值 | 默认 SDK 行为 | 说明 |
|---|---|---|
CREATE |
允许身份切换。 | 由于活动创建,正在发生标识切换。 |
NEW_INTENT |
允许身份切换。 | 正在发生身份切换,因为正在将新意图分配给活动。 |
RESUME_CANCELLED |
阻止身份切换。 | 发生身份切换是因为简历已取消。 当最终用户按 PIN、身份验证或合规性 UI 上的后退按钮时,这种情况最为常见。 |
AppIdentitySwitchResultCallback 参数允许开发人员替代身份开关的默认行为:
public interface AppIdentitySwitchResultCallback {
/**
* @param result
* whether the identity switch can proceed.
*/
void reportIdentitySwitchResult(AppIdentitySwitchResult result);
}
// Where [AppIdentitySwitchResult] is either `SUCCESS` or `FAILURE`.
onMAMIdentitySwitchRequired 为所有隐式标识更改调用,但通过从 . MAMService.onMAMBind返回的 Binder 进行的更改除外。
立即调用的 onMAMIdentitySwitchRequired 默认实现:
callback.reportIdentitySwitchResult(FAILURE)当原因是RESUME_CANCELLED时callback.reportIdentitySwitchResult(SUCCESS)在所有其他情况下。
预计大多数应用不需要以不同的方式阻止或延迟身份切换,但如果应用需要执行此操作,则必须考虑以下几点:
如果阻止了身份切换,则最终用户行为与 SDK 的“从其他应用接收数据”应用保护设置禁止数据入口相同。
如果服务正在主线程上运行,则必须同步调用,
reportIdentitySwitchResult否则 UI 线程将停止响应。若要
Activity创建,将在之前onMAMCreate调用 onMAMIdentitySwitchRequired。 如果应用必须显示 UI 来确定是否允许身份切换,则必须使用 其他 活动显示该 UI。在 中,
Activity当请求切换到空标识且原因为RESUME_CANCELLED时,应用必须修改恢复的活动以显示与该标识切换一致的数据。 如果这不可行,应用应拒绝切换,并且系统将再次要求用户遵守恢复标识 (的策略,例如,通过) 显示应用 PIN 输入屏幕。
警告
多标识应用可以接收来自托管和非托管应用的传入数据。 应用负责以托管方式处理来自托管标识的数据。
如果 (使用 MAMPolicyManager.getIsIdentityOIDManaged 管理请求的标识来检查) ,但应用无法使用该帐户 (例如,因为必须) 先在应用中设置帐户(如电子邮件帐户),然后应拒绝标识切换。
可以通过调用 static MAMActivity.onMAMIdentitySwitchRequired 方法 MAMActivity.defaultOnMAMIdentitySwitchRequired(activity, upn, oid, reason, callback)来访问 的默认行为。
同样,如果您需要重写 MAMActivity.onSwitchMAMIdentityComplete,则可以在不显式继承自 MAMActivity的情况下实现MAMActivityIdentitySwitchListener。
标识切换和屏幕截图限制
Intune App SDK 使用该Window标志FLAG_SECURE强制实施屏幕截图策略。
某些应用也可能为自己的用途而设置 FLAG_SECURE 。
当应用保护策略不限制屏幕截图时,SDK 将不会修改 FLAG_SECURE。
在标识从策略要求禁用屏幕截图的标识切换到策略不要求禁用屏幕截图的标识时,SDK 将清除 FLAG_SECURE。
因此,应用不应在 FLAG_SECURE 标识切换后依赖于保持设置。
在异步操作中保留标识
应用通常从 UI 线程调度后台任务,以处理其他线程上的操作。 多标识应用必须确保这些后台任务使用适当的标识运行,该标识通常与调度它们的活动使用的标识相同。
Intune 应用 SDK 提供 MAMAsyncTask 和 MAMIdentityExecutors 作为方便,以帮助在异步操作中保留标识。 应用必须使用这些 (,或者在任务上显式设置线程标识,) 其异步操作是否可以:
- 将属于托管标识的数据写入文件
- 与其他应用通信
MAMAsyncTask
要使用 MAMAsyncTask,只需从中继承 而不是 和 AsyncTask 的doInBackgroundonPreExecute替代,分别用 和 onPreExecuteMAM 替换。doInBackgroundMAM
MAMAsyncTask构造函数采用活动上下文。
例如:
AsyncTask<Object, Object, Object> task = new MAMAsyncTask<Object, Object, Object>(thisActivity) {
@Override
protected Object doInBackgroundMAM(final Object[] params) {
// Do operations.
}
@Override
protected void onPreExecuteMAM() {
// Do setup.
};
}
MAMAsyncTask 将根据正常优先级顺序假设活动标识。
MAMIdentityExecutors
MAMIdentityExecutors允许您使用 AND 方法将wrapExecutor现有 Executor OR ExecutorService 实例包装为标识保留ExecutorServiceExecutor/。wrapExecutorService 例如
Executor wrappedExecutor = MAMIdentityExecutors.wrapExecutor(originalExecutor, activity);
ExecutorService wrappedService = MAMIdentityExecutors.wrapExecutorService(originalExecutorService, activity);
MAMIdentityExecutors 将根据正常优先级顺序假设活动标识。
文件保护
Writing Protected Files
如上文“按标识组织应用数据”中所述,Intune App SDK 在写入文件时将线程/进程级别) 的活动标识 (与文件相关联。 在文件创建时设置正确的标识对于确保正确的加密和选择性擦除功能至关重要。
应用可以使用 MAMFileProtectionManager 类查询或更改文件的标识,专门 MAMFileProtectionManager.getProtectionInfo 用于查询和 MAMFileProtectionManager.protectForOID 更改。
该 protectForOID 方法还可用于保护目录。
目录保护以递归方式应用于目录中包含的所有文件和子目录。
当目录受到保护时,在该目录中创建的所有新文件都将自动应用相同的保护。
由于目录保护以递归方式应用, protectForOID 因此对于大型目录,调用可能需要一些时间才能完成。
因此,对包含大量文件的目录应用保护的应用可能希望在后台线程上异步运行 protectForOID 。
使用空字符串作为标识参数进行调用将 protectForOID 使用未托管标识标记文件/目录。
如果文件/目录以前已加密,则此操作将从文件/目录中删除加密。
发出选择性擦除命令时,不会删除文件/目录。
警告
请务必确保只有属于特定标识的文件才受该标识的保护。 否则,当拥有者标识注销时,其他标识可能会遇到数据丢失,因为文件将被擦除,加密密钥访问权限将丢失。
显示受保护的文件内容
在 显示 文件内容时设置正确的标识同样重要,以防止未经授权的用户查看托管数据。
SDK 无法自动推断出正在读取的文件与正在显示在 .Activity
应用 必须 正确设置 UI 标识,然后才能显示任何托管数据。
这包括从文件读取的数据。
如果文件来自应用程序外部, (来自 ContentProvider 公共可写位置) 或从公共可写位置读取,则应用程序 必须 尝试使用数据源) 的正确 MAMFileProtectionManager.getProtectionInfo 重载 (确定文件标识,然后再显示从文件读取的信息。
如果报告非 null、非空标识,则 getProtectionInfo 应用 必须 使用 MAMActivity.switchMAMIdentityOID 或 MAMPolicyManager.setUIPolicyIdentityOID 设置 UI 标识以匹配此标识。
如果标识切换失败,则 不得 显示该文件中的数据。
从内容 URI 读取时,可能需要首先通过) 的Uri重载读取getProtectionInfo标识 (,然后相应地设置上下文或线程标识。
必须在打开 ContentResolver文件描述符或输入流之前执行此操作,否则操作可能会失败。
示例流可能如下所示:
用户选择要在应用中打开的文档。
在打开流期间,在从磁盘读取数据之前,应用会确认应用于显示内容的标识:
MAMFileProtectionInfo info = MAMFileProtectionManager.getProtectionInfo(docPath) if (info != null) MAMPolicyManager.setUIPolicyIdentityOID(activity, info.getIdentityOID(), callback, EnumSet.noneOf<IdentitySwitchOption.class>)应用将等待,直到将结果报告给回调。
如果报告的结果为失败,应用不会显示文档。
应用将打开并呈现该文件。
如果应用使用 Android DownloadManager 下载文件,则 SDK 将尝试使用 前面描述的标识优先级自动保护这些文件。
如果未设置线程标识,将使用用于检索 的 DownloadManager 上下文。
如果下载的文件包含公司数据,则当下载后移动或重新创建文件时,应用有责任调用 protectForOID 。
Single-Identity 到多身份的转换
如果以前使用单标识 Intune 集成发布的应用后来集成了多标识,则以前安装的应用将经历转换。 此切换对用户不可见。
应用 不需要 来处理此切换。 转换前创建的所有文件将继续被视为托管 (因此,如果加密策略处于) 状态,它们将保持加密状态。
如果不希望将所有以前的应用数据与托管标识关联,则可以检测此转换并显式删除保护。
- 通过将应用的版本与添加了多身份支持的已知版本进行比较来检测升级。
- 在不希望与托管标识关联的文件或目录上使用空字符串作为标识参数进行调用
protectForOID。
脱机方案
未安装公司门户应用时,Intune 应用 SDK 以“脱机”模式运行。 文件标识标记对脱机模式敏感:
如果未安装公司门户,则无法对文件进行标识标记。 在脱机模式下调用 MAMFileProtectionManager.protectForOID 是安全的,但不会起作用。
如果已安装公司门户,但应用没有应用保护策略,则无法可靠地为文件进行标识标记。
当文件标识标记可用时,以前创建的所有文件都将被视为属于空字符串标识) 的个人/非托管 (,除非应用以前安装为单标识托管应用,如 单标识到多标识转换中所述。
为避免这种情况,在帐户注册成功完成之前,应用应避免创建包含帐户数据的文件。 如果应用绝对必须在脱机状态下创建文件,则可以在 SDK 联机后使用 MAMFileProtectionManager.protectForOID 更正文件的关联标识。
数据缓冲区保护
警告
不建议将属于多个帐户的数据写入单个文件中。 如果可能,请按标识整理应用的文件。
SDK 的 MAMDataProtectionManager 提供用于检查和更改特定数据缓冲区上 OR InputStream 格式的byte[]标记标识的方法。
MAMDataProtectionManager.protectForOID 允许应用将数据与标识相关联,并且如果标识当前是加密策略的目标,则对数据进行加密。
此加密数据适合以文件的形式存储到磁盘上。
MAMDataProtectionManager 还允许您查询与标识关联的数据并对其取消加密。
使用 应 MAMDataProtectionManager 为通知实现 MANAGEMENT_REMOVED 接收器。 有关更多详细信息,请参阅 注册来自 SDK 的通知 。
此通知完成后,如果在) 保护缓冲区时启用了文件加密,则 (通过此类保护的缓冲区将不再可读。
应用可以通过在处理MANAGEMENT_REMOVED通知时调用所有缓冲区来MAMDataProtectionManager.unprotect防止这些缓冲区变得不可读。
如果您想保留身份信息,在此通知期间致电 protectForOID 也是安全的。
加密保证在通知期间被禁用,并且调用 protectForOID 处理程序不会加密数据缓冲区。
警告
在应用过程的早期应避免加密操作。 SDK 将在应用启动后尽早异步执行加密初始化。 但是,如果应用在应用启动时发出加密请求,则在加密初始化完成之前,它可能会被阻止。
注意
Intune 应用 SDK 加密 API 只能用于按照 Intune 策略的要求加密数据。 不会对未启用加密策略的目标帐户应用任何保护,因此它不能用作常规用途加密库。
内容提供商
多标识应用还必须保护通过 ContentProvider共享的数据,以防止不当共享托管内容。
在返回内容之前,应用必须调用静态 MAMContentProvider 方法 isProvideContentAllowedForOid(provider, oid) 。
如果此函数返回 false,则 不得 将内容返回给调用方。
isProvideContentAllowedForOid
ContentProvider如果返回 .ParcelFileDescriptor
通过内容提供程序返回的文件描述符会基于文件标识自动进行处理。
选择性擦除
默认情况下,Intune 应用 SDK 将自动处理选择性擦除,删除与托管标识关联的所有文件。 之后,SDK 将正常关闭应用,完成活动并终止应用进程。
SDK 为应用提供了可选功能 (以补充建议的) 或替代默认擦除行为。
SDK 的默认擦除处理程序不处理受 保护的数据 MAMDataProtectionManager缓冲区。
如果应用使用此功能 ,则必须 补充或替代默认擦除处理程序才能删除该数据。
注意
补充和替代默认擦除行为需要处理特定的 SDK 通知。 有关实现通知处理程序的更多详细信息,请参阅 注册来自 SDK 的通知 。
补充默认擦除行为
为了补充默认的 SDK 擦除行为,应用可以注册 WIPE_USER_AUXILIARY_DATAMAMNotificationType。
在执行默认的选择性擦除 之前 ,SDK 将发送此通知。 SDK 将等待应用的通知处理程序完成,然后删除数据并终止应用。 应用应同步清除数据,并且在所有清理完成后才返回。
应用应强烈考虑使用 WIPE_USER_AUXILIARY_DATA来补充默认擦除行为,因为特定于应用的清理对于多标识应用很常见。
替代默认擦除行为
若要替代默认的 SDK 擦除行为,应用可以注册 WIPE_USER_DATAMAMNotificationType。
警告
应用不得同时WIPE_USER_DATAWIPE_USER_AUXILIARY_DATA注册 和 。
替代默认的 SDK 擦除行为会给应用带来相当大的风险。 应用将全权负责删除与托管标识关联的所有数据,包括已为该标识标记的所有文件和数据缓冲区。
- 如果托管标识受加密保护,并且应用的自定义擦除处理程序未完全删除所有托管数据,则任何剩余的托管文件将保持加密状态。 此数据将无法访问,并且应用可能无法正确处理读取加密数据的尝试。
- 如果应用的擦除处理程序删除未使用托管标识标记的文件,则可能会导致非托管用户的数据丢失。
如果应用的自定义擦除处理程序从文件中删除托管数据,但希望将其他数据保留在文件中,则 必须 通过 MAMFileProtectionManager.protectForOID) 将文件 (的标识更改为非托管标识或空字符串。
覆盖的擦除处理程序应同步清除数据,并且在完成所有清理之前不返回。
请考虑在完成自定义擦除处理程序步骤后手动关闭应用,以防止用户在发生擦除后访问内存中数据。
退出条件
计划投入大量时间来验证应用的多重身份集成。 在开始测试之前:
- 创建应用保护策略并将其分配给帐户。 这将是测试托管帐户。
- 创建,但不要将应用保护策略分配给另一个帐户。 这将是测试的非托管帐户。 或者,如果你的应用支持除 Microsoft Entra 帐户之外的多种帐户类型,则可以使用现有的非 Entra 帐户作为非托管测试帐户。
- 重新熟悉如何在应用中强制实施策略。 多标识测试要求你轻松区分应用何时在强制执行策略的情况下运行,何时未运行。 用于阻止屏幕截图的应用保护策略设置可有效快速测试策略实施。
- 请考虑应用提供的整个 UI 集。 枚举显示帐户数据的屏幕。 您的应用是否只一次显示一个帐户的数据,或者是否可以同时显示属于多个帐户的数据?
- 考虑应用创建的整个文件集。 枚举这些文件中哪些包含属于帐户的数据,而不是系统级数据。
- 确定如何验证每个文件的加密。
- 考虑应用与其他应用交互的整个方式。 枚举所有入口和出口点。 应用可以引入哪些类型的数据? 它广播什么意图? 它实现哪些内容提供商?
- 确定将如何运用这些数据共享功能。
- 准备一台测试设备,该设备具有可与你的应用交互的托管和非托管应用。
- 请考虑您的应用如何使最终用户能够与所有已登录帐户进行交互。 在显示某个帐户的数据之前,用户是否需要手动切换到该帐户?
全面评估应用的当前行为后,通过执行以下一组测试来验证多身份集成。 请注意,这不是一个完整的列表,并不保证应用的多标识实现没有 bug。
验证登录和注销方案
多标识应用最多支持 1 个托管帐户和多个非托管帐户。 这些测试有助于确保多重身份集成不会在用户登录或注销时不正确地更改保护。
对于这些测试,请安装应用和 Intune 公司门户;开始测试前请勿登录。
| 应用场景 | 步骤 |
|---|---|
| 首先登录托管 | - 首先使用托管帐户登录并验证该帐户的数据是否受管理。 - 使用非托管帐户登录并验证该帐户的数据不受管理。 |
| 首先在非托管用户登录 | - 首先使用非托管帐户登录,然后验证该帐户的数据不受管理。 - 使用托管帐户登录并验证该帐户的数据是否受管理。 |
| 登录多个托管 | - 首先使用托管帐户登录并验证该帐户的数据是否受管理。 - 使用第二个托管帐户登录,并验证用户是否被阻止登录,而无需先删除原始托管帐户。 |
| 注销托管 | - 使用托管帐户和非托管帐户登录到您的应用。 - 注销托管帐户。 - 确认已从您的应用中移除受管理帐号,并且该帐号的所有数据都已被移除。 - 确认非托管帐户仍已登录,未删除非托管帐户的任何数据,并且仍未应用策略。 |
| 注销非托管 | - 使用托管帐户和非托管帐户登录到您的应用。 - 注销非托管帐户。 - 确认已从您的应用中移除该非托管帐号,并且该帐号的所有数据都已被移除。 - 确认托管帐号仍已登录,未移除任何非托管帐号的数据,并且仍应用策略。 |
验证活动标识和应用生命周期
您的多标识应用可能会显示包含单个帐号数据的视图,并允许用户显式更改当前正在使用的帐号。 它还可以同时呈现包含多个帐户数据的视图。 这些测试有助于确保多标识集成在整个应用生命周期中为每个页面上的活动标识提供正确的保护。
对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户和非托管帐户登录。
| 应用场景 | 步骤 |
|---|---|
| 单一帐户视图,托管 | - 切换到托管帐户。 - 导航到应用中显示单个帐号数据的所有页面。 - 确认策略应用于每个页面。 |
| 单一帐户视图,非托管 | - 切换到非托管帐户。 - 导航到应用中显示单个帐号数据的所有页面。 - 确认该策略未应用于任何页面。 |
| 多帐户视图 | - 导航到应用程序中同时显示多个帐户数据的所有页面。 - 确认策略应用于每个页面。 |
| 托管暂停 | - 在显示托管数据且策略处于活动状态的屏幕上,通过导航到设备主屏幕或其他应用来暂停应用。 - 恢复应用。 - 确认仍应用该策略。 |
| 非托管暂停 | - 在显示非托管数据且没有处于活动状态的策略的屏幕上,通过导航到设备主屏幕或其他应用来暂停应用。 - 恢复应用。 - 确认未应用该策略。 |
| 托管终止 | - 在显示托管数据且策略处于活动状态的屏幕上,强制终止应用。 - 重新启动应用程序。 - 确认如果应用在受管理帐户数据 (预期) 屏幕上恢复,则仍应用策略。 如果应用在包含非托管帐户数据的屏幕上恢复,请确认未应用该策略。 |
| 非托管终止 | - 在显示非托管数据且策略处于活动状态的屏幕上,强制终止应用。 - 重新启动应用程序。 - 确认,如果应用在屏幕上恢复,且非托管帐户的数据 (预期) ,则不会应用策略。 如果应用在带有托管帐户数据的屏幕上恢复,请确认仍然应用该策略。 |
| 临时身份切换 | - 实验在帐户之间切换并暂停/恢复/终止/重新启动应用程序。 - 确认托管账户的数据始终受到保护,而非托管账户的数据从未受到保护。 |
验证数据共享方案
多标识应用可能会向其他应用发送数据,也可能会从其他应用接收数据。 Intune 的应用保护策略具有规定此行为的设置。 这些测试有助于确保多身份集成遵守这些数据共享设置。
对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户和非托管帐户登录。 此外:
- 将托管帐户的策略设置为:
- 将组织数据发送到其他应用“改为”策略管理的应用“。
- “从其他应用接收数据”到“策略管理的应用”。
- 在测试设备上安装其他应用:
- 一个托管应用,目标 (与你的应用相同的策略,可以发送和接收数据,如 Microsoft Outlook) 。
- 可发送和接收数据的任何非托管应用。
- 使用托管测试帐户登录到其他托管应用。 即使其他托管应用是多标识的,也只能使用托管帐户登录。
如果你的应用能够将数据发送到其他应用,例如 Microsoft Outlook 将文档附件发送到 Microsoft Office:
| 应用场景 | 步骤 |
|---|---|
| 托管标识发送到非托管应用 | - 切换到托管帐户。 - 导航到应用可以发送数据的位置。 - 尝试将数据发送到非托管应用。 - 应阻止你向非托管应用发送数据。 |
| 托管标识发送到托管应用 | - 切换到托管帐户。 - 导航到应用可以发送数据的位置。 - 尝试使用已登录的托管帐户将数据发送到其他托管应用。 - 应允许您将数据发送到托管应用。 |
| 发送到托管应用的非托管标识 | - 切换到非托管帐户。 - 导航到应用可以发送数据的位置。 - 尝试使用已登录的托管帐户将数据发送到其他托管应用。 - 应阻止您将数据发送到其他托管应用。 |
| 发送到非托管应用的非托管标识 | - 切换到非托管帐户。 - 导航到应用可以发送数据的位置。 - 尝试将数据发送到非托管应用。 - 应始终允许您将非托管帐户的数据发送到非托管应用。 |
应用可能会主动从其他应用导入数据,例如 Microsoft Outlook 从 Microsoft OneDrive 附加文件。 应用也可能被动地从其他应用接收数据,例如 Microsoft Office 从 Microsoft Outlook 附件打开文档。 接收应用保护策略设置涵盖这两种场景。
如果您的应用能够主动导入其他应用中的数据:
| 应用场景 | 步骤 |
|---|---|
| 从非托管应用导入托管标识 | - 切换到托管帐户。 - 导航到应用可以从其他应用导入数据的位置。 - 尝试从非托管应用导入数据。 - 应阻止从非托管应用导入数据。 |
| 从托管应用导入托管标识 | - 切换到托管帐户。 - 导航到应用可以从其他应用导入数据的位置。 - 尝试使用已登录的托管帐户从其他托管应用导入数据。 - 应允许从其他托管应用导入数据。 |
| 从托管应用导入非托管标识 | - 切换到非托管帐户。 - 导航到应用可以从其他应用导入数据的位置。 - 尝试使用已登录的托管帐户从其他托管应用导入数据。 - 应阻止从其他托管应用导入数据。 |
| 从非托管应用导入非托管标识 | - 切换到非托管帐户。 - 导航到应用可以从其他应用导入数据的位置。 - 尝试从非托管应用导入数据。 - 应始终允许你从非托管帐户导入数据。 |
如果你的应用能够被动地从其他应用接收数据:
| 应用场景 | 步骤 |
|---|---|
| 从非托管应用接收的托管标识 | - 切换到托管帐户。 - 切换到非托管应用。 - 导航到可以发送数据的位置。 - 尝试将数据从非托管应用发送到您的应用。 - 应用的托管帐号不应能够从非托管应用接收数据。 |
| 从托管应用接收的托管标识 | - 切换到托管帐户。 - 使用已登录的托管帐户切换到其他托管应用。 - 导航到可以发送数据的位置。 - 尝试将数据从托管应用发送到您的应用。 - 应允许应用的托管帐户从其他托管应用接收数据。 |
| 从托管应用接收的非托管标识 | - 切换到非托管帐户。 - 使用已登录的托管帐户切换到其他托管应用。 - 导航到可以发送数据的位置。 - 尝试将数据从托管应用发送到您的应用。 - 应用的非托管帐户不应能够从托管应用接收数据。 |
| 从非托管应用接收的非托管标识 | - 切换到非托管帐户。 - 切换到非托管应用。 - 导航到可以发送数据的位置。 - 尝试将数据从非托管应用发送到您的应用。 - 应始终允许应用的非托管帐户从非托管应用接收数据。 |
如果在这些测试中失败,则可能表明应用在尝试发送或接收数据时没有设置正确的活动标识。 可以通过在发送/接收时利用 SDK 的获取标识 API 来调查此问题,以确认活动标识设置正确。
验证选择性擦除方案
多标识应用可能已补充或重写 SDK 的默认擦除行为。 这些测试有助于确保多身份集成在启动擦除时正确删除托管数据,而不会影响非托管数据。
警告
提醒一下,如果你的应用使用了 MAMDataProtectionManager.protectForOID,则必须实现 OR WIPE_USER_DATA的处理程序。WIPE_USER_AUXILIARY_DATA
对于这些测试,请安装应用和 Intune 公司门户;在开始测试之前,使用托管帐户和非托管帐户登录。 对于这两个帐户,请练习存储帐户数据的应用方案。
| 应用场景 | 先决条件 | 步骤 |
|---|---|---|
| 补充擦除处理程序 | 你的应用已实现处理程序 WIPE_USER_AUXILIARY_DATA |
-
从 Microsoft Intune 管理中心发出选择性擦除。 - 通常通过日志记录) 确认 (擦除处理程序已成功执行。 - 确认已从您的应用中移除受管理帐号,并且该帐号的所有数据都已被移除。 - 确认非托管帐户仍已登录,未删除非托管帐户的任何数据,并且仍未应用策略。 |
| 已替代擦除处理程序 | 你的应用已实现处理程序 WIPE_USER_DATA |
-
从 Microsoft Intune 管理中心发出选择性擦除。 - 通常通过日志记录) 确认 (擦除处理程序已成功执行。 - 确认已从您的应用中移除受管理帐号,并且该帐号的所有数据都已被移除。 - 确认非托管帐户仍已登录,未删除非托管帐户的任何数据,并且仍未应用策略。 - 确认擦除处理程序完成后,应用已正常退出或仍处于正常状态。 |
| 手动文件保护 | - 您的应用程序调用 MAMFileProtectionManager.protectForOID - 应用已实现处理程序 WIPE_USER_DATA |
- 确保已练习过应用手动保护属于托管帐户的至少一个文件的场景。 - 从 Microsoft Intune 管理中心发出选择性擦除。 - 确认文件已删除。 |
| 手动数据缓冲区保护 | - 您的应用程序调用 MAMDataProtectionManager.protectForOID - 应用已实现处理程序 WIPE_USER_AUXILIARY_DATA 或 WIPE_USER_DATA |
- 确保您已练习过您的应用将手动保护属于托管帐户的至少一个数据缓冲区的场景。 - 从 Microsoft Intune 管理中心发出选择性擦除。 - 确认数据缓冲区已从存储它们的任何文件中删除,并且应用仍可以从这些文件中读取非托管数据。 |
后续步骤
完成上述所有 退出条件 后,应用现已成功集成为多标识,可以按标识强制实施应用保护策略。 后续部分(阶段 6:应用程序配置和阶段 7:应用参与功能)可能是必需的,也可能不是必需的,具体取决于应用所需的应用保护策略支持。 如果不确定这些部分中的任何一个是否适用于你的应用,请重新访问 SDK 集成的关键决策。