确保凭据与凭据提供方保持一致

当用户创建通行密钥时,信赖方服务器会保存某些详细信息,而凭据提供程序(例如 Google 密码管理工具)会保存其他详细信息。具体而言:

  • 依赖方服务器会保存公钥凭证。
  • 凭据提供程序会保存用户名、显示名称、私钥和其他关联的元数据。此元数据可帮助用户在登录期间识别并选择所需的通行密钥。

信赖凭据方服务器上保存的数据与凭据提供程序之间可能存在不一致,这可能会导致糟糕的用户体验。在以下情况下可能会出现问题:

  • 凭据在依赖方服务器上被删除,但在凭据提供程序上未被删除,这会导致凭据提供程序向用户显示已删除的凭据。
  • 用户名或显示名称在依赖方服务器上已更新,但在凭据提供程序上未更新,导致凭据提供程序显示过时的详细信息。

借助 Credential Manager 的 Signal API,依赖方可以与凭据提供程序通信,以删除凭据并更新用户元数据(例如用户名和显示名称)。针对不同场景,有三种受支持的请求类型:

  • SignalUnknownCredentialRequest

    • 表示特定凭据不再有效,应在凭据提供程序中隐藏或移除。
  • SignalAllAcceptedCredentialIdsRequest

    • 向凭据提供程序提供已接受的凭据 ID 列表。
  • SignalCurrentUserDetailsRequest

    • 更新用户的元数据详细信息。

版本兼容性

Signal API 适用于搭载 Android 15 或更高版本的设备,并且从 androidx.credentials 库的 1.6.0-beta03 版本开始提供。

实现

如需使用 Signal API,请按以下步骤操作:

  1. 将 Credential Manager 依赖项添加到您的项目中。

    Kotlin

    dependencies {
        implementation("androidx.credentials:credentials:1.7.0-alpha02")
    }

    Groovy

    dependencies {
        implementation "androidx.credentials:credentials:1.7.0-alpha02"
    }

  2. 调用 Signal API

    如需向凭据提供程序发送信号请求,请使用受支持的信号请求。每种信号请求类型都需要一个 JSON 请求,如以下示例所示:

    • 未知凭证 (SignalUnknownCredentialRequest)

      使用 SignalUnknownCredentialRequest 表示凭据被拒绝并被视为未知。当凭证提供程序收到此信号时,会隐藏或删除凭证。

      用法

      当依赖方未能验证通行密钥断言时,请使用此信号。这意味着通行密钥无效,必须由凭证提供方隐藏或移除。

      此请求所需的 JSON 参数为 rpId 和 credentialId。如需详细了解 JSON 结构,请参阅 signalUnknownCredential 选项。

      credentialManager.signalCredentialState(
          SignalUnknownCredentialRequest(
              requestJson = JSONObject().apply {
                  put("rpId", rpId /* [String] RP ID of the relying party */)
                  put("credentialId", credentialId /* [String] Credential ID of the credential to be hidden or deleted */)
              }.toString()
          )
      )
      
    • 所有可接受的凭证 (SignalAllAcceptedCredentialIdsRequest)

      使用 SignalAllAcceptedCredentialIdsRequest 向凭证提供程序通知所有已接受的凭证集。凭据提供程序收到信号后,会隐藏或删除未包含在此列表中的所有凭据,或取消隐藏之前隐藏但现在包含在此列表中的所有凭据。

      用法

      当依赖方未能验证通行密钥时,请使用此信号。 此失败意味着通行密钥无效,必须由凭据提供程序隐藏或移除。每当您需要向凭据提供程序广播一组已知凭据 ID 时,也可以使用此信号。

      此请求所需的 JSON 参数为 rpId、userId 和 allAcceptedCredentialIds。如需详细了解 JSON 结构,请参阅 signalAllAcceptedCredential 选项。

      credentialManager.signalCredentialState(
          SignalAllAcceptedCredentialIdsRequest(
              requestJson = JSONObject().apply {
                  put("rpId", rpId /* [String] RP ID of the relying party */)
                  put("userId", userId /* [String] User ID of the current user */)
                  put(
                      "allAcceptedCredentialIds",
                      JSONArray(credentialIdsList /* [List<String>] List of accepted Credential IDs */)
                  )
              }.toString()
          )
      )
      
    • 当前用户详细信息 (SignalCurrentUserDetailsRequest)

      使用 SignalCurrentUserDetailsRequest 通知凭证提供程序,特定用户的元数据(例如用户名和显示名称)已更新,应显示在凭证提供程序中。

      用法

      当用户或依赖方更新与用户账号关联的通行密钥元数据时,请使用此信号。

      此请求所需的 JSON 参数为 rpId、userId、name 和 displayName。如需详细了解 JSON 结构,请参阅 signalCurrentUserDetails 选项。

      credentialManager.signalCredentialState(
          SignalCurrentUserDetailsRequest(
              requestJson = JSONObject().apply {
                  put("rpId", rpId /* [String] RP ID of the relying party */)
                  put("userId", userId /* [String] User ID of the current user */)
                  put("name", name /* [String] New Name to be updated for the current user */)
                  put("displayName", displayName /* [String] New display name to be updated for the current user */)
              }.toString()
          )
      )
      

测试实现

如需测试 Signal API 的实现情况,请完成以下步骤:

  1. 安装名为 MyVault 的凭据提供程序示例。

  2. 在设置 > 密码、通行密钥和账号 > 首选服务中,将 MyVault 启用为凭据提供程序。

    Android 设置中的“首选服务”菜单,其中显示 MyVault 已启用为凭据提供程序。

  3. 在设置 > 应用 > MyVault > 通知中为 MyVault 启用所有通知。

    MyVault 应用的“通知”菜单,其中显示已启用所有通知。

  4. 在设置 > 应用 > MyVault > 通知 > 类别 > Signal API 通知渠道中,验证在屏幕上弹出是否已针对通知开启。

    MyVault 的 Signal API 通知渠道设置,其中显示“在屏幕上弹出”选项已启用。

  5. 在应用中,触发向凭据提供程序发送信号请求的流程。您应该会在屏幕上看到来自 MyVault 的通知。 这可以验证凭证提供程序是否收到了请求。