安全

本指南中的功能介绍了您可以 在设备政策控制器 (DPC) 应用中实现这些功能。此文档 包含代码示例,您还可以将 Test DPC 应用用作 Android 企业功能的示例代码来源。

DPC 应用可以在个人设备或设备所有者中以资料所有者模式运行 模式。下表显示了可用的功能 当 DPC 于资料所有者模式或设备所有者模式下运行时:

功能 个人资料所有者 设备所有者
禁止访问应用
屏蔽来自未知来源的应用
限制 Google Play 中的账号
启用企业恢复出厂设置保护功能
监控企业进程日志和远程 bug 报告
授予对客户端证书的访问权限和移除对客户端证书的访问权限
安全密码重置
工作资料安全验证

禁止访问应用

适用于希望禁止员工玩游戏或观看视频的组织 在一天中的特定时段通过 Android 设备使用 YouTube,或者 设备政策控制器 (DPC) 可以暂时停用对应用的访问权限。

如需停用对应用的访问权限,请在设备所有者或个人资料所有者模式下运行的 DPC 配置 setPackagesSuspended(),然后所选应用就会 (Google 启动器会将该应用显示为灰色)。当用户点按该应用时 系统会显示一个系统对话框,说明应用已暂停。

应用在暂停期间无法启动 Activity,且通知 软件包。已暂停的软件包未显示在概览中 屏幕,则无法显示对话框(包括消息框和信息条),并且 无法播放音频或振动设备。

启动器可以通过调用 isPackageSuspended() 方法。详细了解如何配置应用 请参阅 setPackagesSuspended

屏蔽来自未知来源的应用

不是从 Google Play(或其他受信任的应用商店)安装的应用 称为来自未知来源的应用。设备和数据可能面临更高的风险 当用户安装这些应用时触发。

为防止有人安装来自未知来源的应用, 全托管式设备和工作资料可以添加 DISALLOW_INSTALL_UNKNOWN_SOURCES 用户限制。

工作资料设备级限制

当工作资料管理员添加 DISALLOW_INSTALL_UNKNOWN_SOURCES 后, 此限制仅适用于工作资料然而,单位的管理员 个人资料可通过设置 托管配置(适用于 Google Play)。设备级限制为 适用于 Android 8.0(或更高版本)且已安装 Google Play 应用 80812500 或更高版本。

如需限制在 Google Play 中安装应用,请按以下步骤操作:

  1. 为 Google Play 软件包设置受管配置包 com.android.vending
  2. 在包中,为 verify_apps:device_wide_unknown_source_block 键。
  3. 添加 ENSURE_VERIFY_APPS 用户限制。

以下示例展示了如何检查 Google Play 是否支持此 并将值设置为 true

Kotlin

internal val DEVICE_WIDE_UNKNOWN_SOURCES = "verify_apps:device_wide_unknown_source_block"
internal val GOOGLE_PLAY_APK = "com.android.vending"

// ...

// Add the setting to Google Play's existing managed config. Supported in
// Google Play version 80812500 or higher--older versions ignore unsupported
// settings.
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
var existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DEVICE_WIDE_UNKNOWN_SOURCES, true)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

// Make sure that Google Play Protect verifies apps.
dpm.addUserRestriction(adminName, UserManager.ENSURE_VERIFY_APPS)
dpm.addUserRestriction(adminName, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)

Java

static final String DEVICE_WIDE_UNKNOWN_SOURCES =
    "verify_apps:device_wide_unknown_source_block";
static final String GOOGLE_PLAY_APK = "com.android.vending";

// ...


// Add the setting to Google Play's existing managed config. Supported in
// Google Play version 80812500 or higher--older versions ignore unsupported
// settings.
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
Bundle existingConfig =
    dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DEVICE_WIDE_UNKNOWN_SOURCES, true);
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

// Make sure that Google Play Protect verifies apps.
dpm.addUserRestriction(adminName, UserManager.ENSURE_VERIFY_APPS);
dpm.addUserRestriction(adminName, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);

系统设置中的界面仍然有效,但系统阻止 应用安装。此限制会影响以后的安装, 已安装的应用会保留在设备上。设备用户可以继续安装应用 Android 调试桥 (adb) 导入到个人资料中。

如需详细了解未知来源,请参阅备选分发方式 选项

限制 Google Play 中的账号

有时,单位可能希望允许用户添加个人 Google 账号, 账号(例如在 Gmail 中阅读邮件),但不想要个人 安装应用。您的设备政策控制器 (DPC) 可以设置用户可使用的账号列表 Google Play。

全托管式设备或工作资料的管理员组件可以限制 为 Google Play 设置托管配置即可。账号 当安装的 Google Play 应用版本为 80970100 时,限制可用 或更高版本。

如需限制 Google Play 中的账号数量,请执行以下操作:

  1. 为 Google Play 软件包设置受管配置包 com.android.vending
  2. 在邮件分类中,输入以英文逗号分隔的电子邮件地址,作为 allowed_accounts 键。

以下示例展示了如何限制账号:

Kotlin

internal val ALLOWED_ACCOUNTS = "allowed_accounts"
internal val GOOGLE_PLAY_APK = "com.android.vending"

// ...

// Limit Google Play to one work and one personal account. Use
// a comma-separated list of account email addresses (usernames).
val googleAccounts = "ali@gmail.com,ali.connors@example.com"

// Supported in Google Play version 80970100 or higher.
val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putString(ALLOWED_ACCOUNTS, googleAccounts)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

Java

static final String ALLOWED_ACCOUNTS = "allowed_accounts";
static final String GOOGLE_PLAY_APK = "com.android.vending";

// ...


// Limit Google Play to one work and one personal account. Use
// a comma-separated list of account email addresses (usernames).
String googleAccounts = "ali@gmail.com,ali.connors@example.com";

// Supported in Google Play version 80970100 or higher.
Bundle existingConfig =
    dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putString(ALLOWED_ACCOUNTS, googleAccounts);
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

要限制 Google Play 仅使用工作账号,请将 allowed_accounts 设置为 设备政策控制器 (DPC) 获知该账号的电子邮件地址后,便立即注册为单个受管理的账号。一个 空字符串可防止用户在 Google Play 中使用任何账号。

启用企业恢复出厂设置保护功能

借助企业恢复出厂设置保护功能,组织可以指定 Google 账号可以配置恢复出厂设置的设备。

消费者恢复出厂设置保护功能旨在防止设备被盗。之前 允许任何人在未经授权且恢复出厂设置后配置设备(例如 与使用 EMM 一样,则设置向导会要求用户针对所有来源进行身份验证 之前位于设备个人资料中的 Google 账号。

在企业环境中,恢复出厂设置是用于管理 员工设备。但是,如果 组织不知道员工的账号凭据,恢复出厂设置 可能会阻止组织向其他设备发放设备 员工。

在恢复出厂设置后控制配置

在设备所有者模式下运行时,您的 DPC 可以使用 setFactoryResetProtectionPolicy(),用于控制 有权在恢复出厂设置后配置设备。如果此配置 设为 null 或设为空列表,则有权配置的账号 恢复出厂设置后的设备上 设备。

DPC 可以在完全受管的整个生命周期内配置这些账号 设备。

  1. IT 管理员可以使用 People API 中的 people.get 方法 并使用特殊值 me。这将检索 userId 已登录的账户。userID 将在 resourceName 键中返回, people/[userId] 形式的整数字符串。新创建的账号 在 72 小时内无法恢复出厂设置。
  2. 您可能还需要允许一位或多位 IT 管理员在设备恢复完毕后解锁设备 恢复出厂设置。让以下每一位 IT 管理员登录各自的 Google 账号 同样按照第 1 步操作,并与您分享其userId,这样您就可以添加这些 userIds 添加到下一步中。
  3. DPC 使用 setFactoryResetProtectionPolicy() 设置 userId 列表, 配置恢复出厂设置的设备。
  4. DPC 启用可在出厂后配置设备的账号 通过发送广播重置 将 com.google.android.gms.auth.FRP_CONFIG_CHANGED 作为显式 intent 来 防止因后台限制而被丢弃。

Kotlin

const val ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

// List of userId that can provision a factory reset device.
// You can use the value returned calling people/me endpoint.
val accountIds = listOf("000000000000000000000")

dpm.setFactoryResetProtectionPolicy(
    adminName,
    FactoryResetProtectionPolicy.Builder()
        .setFactoryResetProtectionAccounts(accountIds)
        .setFactoryResetProtectionEnabled(true)
        .build()
)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

// List of userId that can provision a factory reset device.
// You can use the value returned calling people/me endpoint.
List<String> accountIds = new ArrayList<String>();
accountIds.add("000000000000000000000");

dpm.setFactoryResetProtectionPolicy(
    adminName,
    new FactoryResetProtectionPolicy.Builder()
        .setFactoryResetProtectionAccounts(accountIds)
        .setFactoryResetProtectionEnabled(true)
        .build());

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Legacy

适用于无法使用 setFactoryResetProtectionPolicy()(引入 API 级别 30,您的 DPC 可以使用 setApplicationRestrictions 添加 将所选账号应用于 factoryResetProtectionAdmin 受管配置 (针对 com.google.android.gms 软件包)。

Kotlin

const val GOOGLE_PLAY_APK = "com.android.vending"
const val FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin"
const val DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, false)
newConfig.putString(FACTORY_RESET_PROTECTION_ADMIN, googleAccounts)
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String GOOGLE_PLAY_APK = "com.android.vending";
static final String FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin";
static final String DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

Bundle existingConfig =
        dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, false);
newConfig.putStringArray(FACTORY_RESET_PROTECTION_ADMIN,
        accountIds.toArray(new String[accountIds.size()]));
dpm.setApplicationRestrictions(adminName, GOOGLE_PLAY_APK, newConfig);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

停用企业恢复出厂设置保护

如需停用恢复出厂设置保护,您的 DPC 可以使用 setFactoryResetProtectionPolicy()传递值 null

Kotlin

const val ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

dpm.setFactoryResetProtectionPolicy(adminName, null)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String ACTION_FRP_CONFIG_CHANGED =
    "com.google.android.gms.auth.FRP_CONFIG_CHANGED";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

dpm.setFactoryResetProtectionPolicy(adminName, null);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

Legacy

适用于无法使用 setFactoryResetProtectionPolicy()(引入 API 级别 30,您的 DPC 可以使用 setApplicationRestrictions 设置密钥 所管理的 disableFactoryResetProtectionAdmintrue 的值 com.google.android.gms 软件包的配置。

Kotlin

const val GOOGLE_PLAY_APK = "com.android.vending"
const val FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin"
const val DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin"
const val GMSCORE_PACKAGE = "com.google.android.gms"

// ...

val existingConfig = dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK)
val newConfig = Bundle(existingConfig)
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, true)

dpm.setApplicationRestrictions(
    adminName, GOOGLE_PLAY_SERVICES_PACKAGE, restrictions
)

val frpChangedIntent = Intent(ACTION_FRP_CONFIG_CHANGED)

frpChangedIntent.setPackage(GMSCORE_PACKAGE)
context.sendBroadcast(frpChangedIntent)

Java

static final String GOOGLE_PLAY_APK = "com.android.vending";
static final String FACTORY_RESET_PROTECTION_ADMIN = "factoryResetProtectionAdmin";
static final String DISABLE_FACTORY_RESET_PROTECTION_ADMIN = "disableFactoryResetProtectionAdmin";
static final String GMSCORE_PACKAGE = "com.google.android.gms";

// ...

Bundle existingConfig =
        dpm.getApplicationRestrictions(adminName, GOOGLE_PLAY_APK);
Bundle newConfig = new Bundle(existingConfig);
newConfig.putBoolean(DISABLE_FACTORY_RESET_PROTECTION_ADMIN, true);

dpm.setApplicationRestrictions(
    adminName, GOOGLE_PLAY_SERVICES_PACKAGE, restrictions);

Intent frpChangedIntent = new Intent(ACTION_FRP_CONFIG_CHANGED);

frpChangedIntent.setPackage(GMSCORE_PACKAGE);
context.sendBroadcast(frpChangedIntent);

监控企业进程日志和远程错误报告

在 EMM 控制台中,管理员可以使用企业版监控全托管式设备 进程日志和远程错误报告

记录企业设备活动

在设备所有者模式下运行的 DPC 可远程识别可疑活动 跟踪设备活动,包括应用启动、Android 调试桥 (adb) activity 和屏幕解锁。进程日志不要求用户同意。

如需启用或停用日志记录,DPC 会调用 setSecurityLoggingEnabled()

当有新一批日志可用时,DeviceAdminReceiver 会收到 onSecurityLogsAvailable() 回调。要检索日志(在 接收回调),DPC 调用 retrieveSecurityLogs()

DPC 还可以调用 retrievePreRebootSecurityLogs() 来获取安全性 上一个重新启动周期生成的日志。这是指 上次设备重新启动时间以及之前的重新启动时间。不支持的设备 retrieveSecurityLogs() 会返回 null。如果您的应用同时使用 retrievePreRebootSecurityLogs()retrieveSecurityLogs(),您需要 检查是否存在重复条目。
注意:此功能只会记录全托管式设备上的活动, 用户或关联用户。此功能不支持 个人设备,因为它会记录设备级活动。

此设置在安全事件后审核中非常有用,因为它会记录 以下操作类型:

  • 每次应用刚启动时。这有助于确定是否存在 以被侵应用开头的恶意软件。
  • 设备上尝试解锁失败的次数。这样可以确定 短时间内多次尝试解锁失败。
  • 用户连接时可能有害的 adb 命令 通过 USB 线将设备连接到计算机。

如需详细了解如何读取日志,请参阅 SecurityLog

在开发和测试过程中,您可以强制系统 即 DPC 可访问的现有安全日志 。在 Android 9.0(API 级别 28)或更高版本中,运行以下命令 Android 调试桥 (adb) 命令:

adb shell dpm force-security-logs

系统会限制您使用该工具的频率,并报告任何 输出速度会有意减慢。如果有可用的日志, DPC 接收 onSecurityLogsAvailable() 回调。

远程请求 bug 报告

在设备所有者模式下运行的 DPC 可以远程请求用户提交 bug 报告 只有一位用户或关联用户的设备。bug 报告会 在请求 bug 报告那一刻查看设备活动,但也可能是 包含前几个小时的活动,具体取决于 logcat 的频率 缓冲区刷新。

如需远程请求 bug 报告,DPC 会调用 requestBugreport()

授予客户端证书的访问权限和移除对客户端证书的访问权限

如果在资料所有者或设备所有者模式下运行的 DPC 向第三方应用授予了权限 能够管理证书,那么应用可向自己授予 证书会自行安装。要安装 证书中的所有应用都可以访问的证书,请使用 installKeyPair()

如需了解要配置的参数,请参阅 installKeyPair()。此功能 与现有 API 结合使用来管理证书。

部署场景

如果没有 installKeyPair() 方法:

  • 用户需要点按证书名称,然后每次都点按允许 他们希望授予证书的访问权限
  • 用户在安装证书时会看到一条提示, 证书。

使用 installKeyPair() 方法:

  • 用户每次想要向特定网域授予访问权限时,都无需点按允许 证书。
  • 用户无法重命名证书。
  • 管理员可以更好地控制证书,因为他们可以屏蔽 不应有权访问特定证书的应用。

移除客户端证书

授予对客户端证书的访问权限之后(远程移除客户端) 通过 installKeyPair() 安装证书,调用 removeKeyPair()

在设备所有者模式或资料所有者模式下运行的 DPC 或委托 DPC 证书安装程序可以调用 removeKeyPair()。这会移除 证书和私钥对安装在给定私钥别名下。

部署场景

如果组织要迁移到更安全的客户端形式,请使用此功能 证书。如果管理员发布了新证书及其发行版 需要花费大量时间,那么管理员可撤消已弃用的 并在迁移完成后指定证书

安全密码已重置

DPC 可以使用 安全令牌设备所有者和资料所有者可以调用 Secure 用于更改设备和工作资料密码的密码重置 API 。安全密码重置功能会将resetPassword()替换为 进行了以下改进:

如果您的 DPC build 以 Android 8.0 (API) 为目标平台,则应使用安全密码重置功能 级别 26)或更高版本。调用 resetPassword() 会抛出 SecurityException(在以 Android 8.0 或更高版本为目标平台的 DPC 中),因此您可能需要 需要更新设备政策控制器 (DPC)。

设置和激活令牌

您的 DPC 需要设置并激活令牌才能重置密码。因为 您的 DPC 可能无法立即使用该令牌,您可以设置令牌 IT 管理员可能需要使用它。

密码重置令牌是一个加密的强随机值, 长度至少为 32 个字节。为每台设备和每个配置文件创建一个令牌,请勿 重复使用或共享生成的令牌。

我们建议将令牌或解密加密令牌的方法存储在 服务器。如果您将令牌本地存储在凭据加密存储空间中,您的 DPC 在用户解锁设备或个人资料之前无法重置密码。如果您 将令牌本地存储在设备加密存储空间中 因此攻击者可能会使用此令牌 获取对工作资料或主目录的访问权限 用户。

您可以在 DPC 中生成新令牌或从服务器提取令牌。通过 下例所示为 DPC 自行生成令牌并将其报告给 服务器:

Kotlin

val token = ByteArray(32)

// Generate a new token
val random = SecureRandom()
random.nextBytes(token)

// Set the token to use at a later date
val success: Boolean
success = dpm.setResetPasswordToken(DeviceAdminReceiver.getComponentName(context), token)

// Activate the token and update success variable...

// Store the token on a server
if (success) {
 sendTokenToServer(token)
}

Java

byte token[] = new byte[32]; // Minimum size token accepted

// Generate a new token
SecureRandom random = new SecureRandom();
random.nextBytes(token);

// Set the token to use at a later date
boolean success;
success = dpm.setResetPasswordToken(DeviceAdminReceiver.getComponentName(getContext()), token);

// Activate the token and update success variable ...

// Store the token on a server
if (success) {
 sendTokenToServer(token);
}

在大多数情况下,DPC 需要在设置令牌后将其激活。但是,当 如果用户没有锁定屏幕密码,则系统会激活令牌 。要激活令牌,请让用户确认其凭据。 您的 DPC 可以调用 KeyguardManager 方法 createConfirmDeviceCredentialIntent()以获得Intent启动 确认。在界面中向设备用户说明 要求他们进行身份验证以下代码段展示了如何启用 令牌:

Kotlin

// In your DPC, you'll need to localize the user prompt
val ACTIVATE_TOKEN_PROMPT = "Use your credentials to enable remote password reset"
val ACTIVATE_TOKEN_REQUEST = 1

// Create or fetch a token and set it in setResetPasswordToken() ...
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, ACTIVATE_TOKEN_PROMPT)

if (confirmIntent != null) {
 startActivityForResult(confirmIntent, ACTIVATE_TOKEN_REQUEST)
 // Check your onActivityResult() callback for RESULT_OK
} else {
 // Null means the user doesn't have a lock screen so the token is already active.
 // Call isResetPasswordTokenActive() if you need to confirm
}

Java

// In your DPC, you'll need to localize the user prompt
static final String ACTIVATE_TOKEN_PROMPT =
 "Use your credentials to enable remote password reset";
static final int ACTIVATE_TOKEN_REQUEST = 1;

// Create or fetch a token and set it in setResetPasswordToken() ...

KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
Intent confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(
  null, ACTIVATE_TOKEN_PROMPT);

if (confirmIntent != null) {
 startActivityForResult(confirmIntent, ACTIVATE_TOKEN_REQUEST);
 // Check your onActivityResult() callback for RESULT_OK
} else {
 // Null means the user doesn't have a lock screen so the token is already active.
 // Call isResetPasswordTokenActive() if you need to confirm
}

您需要在设备重新启动前激活 DPC 设置的令牌。Android 设备 在内存中存储未激活的令牌, 重新启动。如果用户在激活令牌之前重新启动设备,您的 DPC 可以 请再次设置相同的令牌或生成新令牌。

您的 DPC 可通过调用 isResetPasswordTokenActive(),检查结果为 true

DPC 设置并激活令牌后,该令牌将一直有效,直到 DPC 删除或 替换令牌(或设备恢复出厂设置)。该令牌与 并且不受用户更改或清除密码的影响。

删除令牌

您可以调用 clearResetPasswordToken() 来删除 DPC 的令牌 。您可能需要撤消已遭破解的令牌,或者 移除重置密码的功能。以下示例展示了如何 设备政策控制器 (DPC) 中:

Kotlin

val dpm = getDpm()
val admin = DeviceAdminReceiver.getComponentName(requireActivity())

// Clear the token
if (!dpm.clearResetPasswordToken(admin)) {
 // Report the failure and possibly try later ...
}

Java

DevicePolicyManager dpm = getDpm();
ComponentName admin = DeviceAdminReceiver.getComponentName(getActivity());

// Clear the token
if (!dpm.clearResetPasswordToken(admin)) {
 // Report the failure and possibly try later ...
}

重置密码

当 IT 管理员需要重置密码时,请致电 resetPasswordWithToken(),并传递您的 DPC 设置并启用的令牌 :

Kotlin

val token: ByteArray = getTokenFromServer()
val newPassword = "password"

try {
 val result: Boolean = dpm.resetPasswordWithToken(
 DeviceAdminReceiver.getComponentName(requireContext()),
 newPassword,
 token,
 0
 )

 if (result) {
 // The password is now 'password'
 } else {
 // Using 'password' doesn't meet password restrictions
 }
} catch (e: IllegalStateException) {
 // The token doesn't match the one set earlier.
}

Java

byte token[] = getTokenFromServer();
String newPassword = "password";

try {
 boolean result = dpm.resetPasswordWithToken(
  DeviceAdminReceiver.getComponentName(getContext()), newPassword, token, 0);

 if (result) {
 // The password is now 'password'
 } else {
 // Using `password` doesn't meet password restrictions
 }
} catch (IllegalStateException e) {
 // The token doesn't match the one set earlier.
}

resetPasswordWithToken() 的调用会返回 false,但密码未返回 更改:

  • 字符数满足任何最小密码长度限制条件。致电 getPasswordMinimumLength()来了解 管理员设置长度限制。
  • 密码中字符的范围和复杂程度与组合相符 限制条件。致电 getPasswordQuality() 以了解 IT 人员是否 管理员设置了组合限制条件。

如果密码质量限制条件不要求设置密码,您可以 向 resetPasswordWithToken() 传递 null 或空字符串即可移除 密码。

工作资料安全性挑战

在资料所有者模式下运行的 DPC 可以要求用户指定安全设置 挑战。系统会显示 挑战。如果用户成功 完成安全验证,系统会解锁工作资料,并 解密文件(如有必要)。

工作资料安全验证的运作方式

  1. 如果 DPC 发送 ACTION_SET_NEW_PASSWORD intent,系统会提示 由用户设置安全验证
  2. DPC 还可以发送 ACTION_SET_NEW_PARENT_PROFILE_PASSWORD intent 来提示用户设置设备锁定。

DPC 可以针对工作挑战设置与 其他设备密码政策例如, 设备质询响应可以不同于 密码。DPC 使用 DevicePolicyManager 方法,例如 setPasswordQuality()setPasswordMinimumLength()

注意事项

  • DPC 可以重置工作资料的密码,但无法重置 设备(个人)密码。如果用户选择设置工作密码和个人密码 相同,那么对工作资料使用 resetPassword() 会使 仅在工作资料中重置密码,且密码不同 用作设备锁定屏幕的按钮
  • DPC 可以使用 setOrganizationColor()setOrganizationName()
  • 设备管理员无法使用 resetPassword() 清除或更改密码 已经设置的应用设备管理员仍然可以设置密码,但只能 当设备没有密码、PIN 码或图案时。

如需了解详情,请参阅 getParentProfileInstance() 和参考文档 DevicePolicyManager 下的文档。