教程:在 Android 应用中支持 Web 回退

本教程演示了 isBrowserRequired() 错误是如何发生的以及如何解决它。 实用工具方法 isBrowserRequired() 检查在本机身份验证不足以功能正常、安全地完成身份验证流程的各种情况下是否需要回退机制。

本教程介绍如何执行下列操作:

  • 检查 isBrowserRequired()
  • 处理 isBrowserRequired()

先决条件

Web 回退

对于本机身份验证不足以完成用户身份验证流程的情况,请使用 Web 回退机制

初始化 Android SDK 时,请指定移动应用程序支持的质询类型,例如 oob 和密码

如果客户端应用无法支持 Microsoft Entra 要求的质询类型,Microsoft Entra 的响应将指示客户端应用需要继续在浏览器中执行身份验证流程。 例如,使用 oob 质询类型初始化 SDK,但在 Microsoft Entra 管理中心,使用带有密码身份验证方法的电子邮件配置应用

在这种情况下,实用工具方法 isBrowserRequired() 返回 true。

示例流程

让我们看看返回 isBrowserRequired() 的示例流,以及如何处理它:

  1. 在初始化期间传递给 SDK 的 JSON 配置文件中,仅添加 oob 质询类型,如以下代码片段所示

    PublicClientApplication.createNativeAuthPublicClientApplication( 
        requireContext(), 
        R.raw.native_auth_config  // JSON configuration file 
    ) 
    

    native_auth_config.json 配置具有以下代码片段:

    {
      "client_id" : "{Enter_the_Application_Id_Here}",
       "authorities" : [
        {
          "type": "CIAM",
          "authority_url": "https://{Enter_the_Tenant_Subdomain_Here}.ciamlogin.com/{Enter_the_Tenant_Subdomain_Here}.onmicrosoft.com/"
        }
      ],
      "challenge_types" : ["oob"],
      "logging": {
        "pii_enabled": false,
        "log_level": "INFO",
        "logcat_enabled": true
      }
    } 
    
  2. 在 Microsoft Entra 管理中心,配置用户流以使用带密码的电子邮件作为身份验证方法

  3. 使用 SDK 的 signUp(username) 方法启动注册流。 你将获得一个通过了 isBrowserRequired() 检查的 SignUpError,因为 Microsoft Entra 需要密码和 oob 质询类型,但你仅使用 oob 配置了 SDK

  4. 若要检查和处理 isBrowserRequired(),请使用以下代码片段:

    val actionResult = authClient.signUp( 
        username = email 
    ) 
    if (actionResult is SignUpError && actionResult.isBrowserRequired()) { 
        // Handle "browser required" error
    } 
    

    该代码表示无法通过本机身份验证完成身份验证流,必须使用浏览器。

处理 isBrowserRequired() 错误

若要处理此错误,客户端应用程序需要启动浏览器并重启身份验证流。 为此,可以使用 Microsoft 身份验证库 (MSAL) acquireToken() 方法。

为此,请按照以下步骤操作:

  1. 若要将重定向 URI 添加到你之前注册的应用,请使用添加平台重定向 URL 中的步骤。

  2. 若要更新客户端应用的配置文件,请使用在 SDK 配置中配置重定向 URI 中的步骤。

  3. 使用以下代码片段通过 acquireToken() 方法获取令牌:

    val actionResult = authClient.signUp(
        username = email
    )
    if (actionResult is SignUpError && actionResult.isBrowserRequired()) {
        authClient.acquireToken(
            AcquireTokenParameters(
                AcquireTokenParameters.Builder()
                    .startAuthorizationFromActivity(requireActivity())
                    .withScopes(getScopes())
                    .withCallback(getAuthInteractiveCallback())
            )
            // Result will contain account and tokens retrieved through the browser.
        )
    } 
    

通过本机身份验证流获得的安全令牌(即 ID 令牌、访问令牌和刷新令牌)与通过浏览器委托流获得的令牌相同。