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

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

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

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

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

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

  • SignalUnknownCredentialRequest

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

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

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

版本兼容性

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

实现

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

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

    Kotlin

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

    Groovy

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

  2. 调用 Signal API

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

    • 未知凭据 (SignalUnknownCredentialRequest)

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

      用法

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

      此请求所需的 JSON 参数为 rpIdcredentialId。如需详细了解 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 参数为 rpIduserIdallAcceptedCredentialIds。如需详细了解 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 参数为 rpIduserIdnamedisplayName。如需详细了解 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 的通知。这会验证凭据提供方是否收到了请求。