You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中Azure B2C MFA验证失败时,如何获取详细异常信息?

问题:从MSAL异常中获取Azure B2C的详细错误信息

现有代码

令牌获取扩展方法

public static async Task<AuthenticationResult> AcquireTokenAsync(this IPublicClientApplication publicClientApp)
{
   try
   {
      var accounts = await publicClientApp.GetAccountsAsync();

      return await Task.Run(() =>
                publicClientApp
                    .AcquireTokenInteractive(apiScopes)
                    .WithAccount(accounts.FirstOrDefault())
                    .WithPrompt(Prompt.ForceLogin)
                    .ExecuteAsync());
   }
   catch (MsalClientException ex)
   {
       if (ex.ErrorCode.Equals("authentication_canceled"))
       {
           log.Info("Authentication was cancelled");
       }

       log.Error("Error in login sequence", ex);
       throw;
   }
}

PublicClientApplication 创建代码

app = PublicClientApplicationBuilder.Create(ClientId)
                        .WithB2CAuthority(Authority)
                        .Build();

当前场景与问题

目前已能捕获用户取消认证窗口的场景(对应错误码authentication_canceled的MsalClientException),但当用户多次MFA验证失败后,AcquireTokenInteractive抛出的是错误码为authentication_ui_failed的MsalClientException,异常信息仅显示:

Microsoft.Identity.Client.MsalClientException:
The browser based authentication dialog failed to complete. Reason: The server encountered an unexpected condition that prevented it from fulfilling the request.

但通过Fiddler抓包可以看到Azure B2C返回的明确错误:

status=500 Internal Server Error
error=server_error
error_description=AADB2C90151: User has exceeded the maximum number for retries for multi-factor authentication.

提问:是否可以从AcquireTokenInteractive抛出的异常中直接获取这类详细的B2C错误信息?


解决方案

1. 启用MSAL详细日志

通过配置MSAL日志,可以捕获到B2C返回的原始错误信息。在创建PublicClientApplication时添加日志配置:

app = PublicClientApplicationBuilder.Create(ClientId)
    .WithB2CAuthority(Authority)
    .WithLogging((level, message, containsPii) =>
    {
        if (level == LogLevel.Error)
        {
            log.Error($"MSAL Error Detail: {message}");
        }
    }, LogLevel.Error)
    .Build();

日志中会包含B2C返回的完整错误描述,包括AADB2C90151这类具体错误码。

2. 扩展异常捕获范围与逻辑

MSAL在交互式认证流程中,部分B2C服务器错误可能被包装为MsalClientException或MsalServiceException,需要扩展捕获逻辑并提取错误信息:

public static async Task<AuthenticationResult> AcquireTokenAsync(this IPublicClientApplication publicClientApp)
{
    try
    {
        var accounts = await publicClientApp.GetAccountsAsync();

        // 移除不必要的Task.Run包装,ExecuteAsync本身就是异步方法
        return await publicClientApp
            .AcquireTokenInteractive(apiScopes)
            .WithAccount(accounts.FirstOrDefault())
            .WithPrompt(Prompt.ForceLogin)
            .ExecuteAsync();
    }
    catch (MsalClientException ex)
    {
        if (ex.ErrorCode.Equals("authentication_canceled"))
        {
            log.Info("Authentication was cancelled");
        }
        else if (ex.ErrorCode.Equals("authentication_ui_failed"))
        {
            // 从异常消息中提取B2C具体错误码
            if (ex.Message.Contains("AADB2C90151"))
            {
                log.Info("User has exceeded the maximum number of MFA retries");
            }
            log.Error("Authentication UI failed", ex);
        }
        else
        {
            log.Error("Client-side authentication error", ex);
        }
        throw;
    }
    catch (MsalServiceException ex)
    {
        // 直接捕获B2C服务器返回的错误码
        if (ex.ErrorCode.StartsWith("AADB2C"))
        {
            log.Info($"B2C Server Error: {ex.ErrorCode} - {ex.Message}");
        }
        log.Error("B2C service authentication error", ex);
        throw;
    }
    catch (Exception ex)
    {
        log.Error("Unexpected authentication error", ex);
        throw;
    }
}

3. 额外提示

  • 避免用Task.Run包装异步方法ExecuteAsync,这会导致不必要的线程切换,降低性能。
  • 若异常被包装在AggregateException中,可通过ex.InnerExceptions遍历提取详细错误信息。

内容的提问来源于stack exchange,提问作者RollerMobster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:09:51