处理 MSAL.js 中的错误和异常

本文概述不同类型的错误,并提供处理常见登录错误的相关建议。

MSAL 错误处理基础知识

Microsoft 身份验证库 (MSAL) 中的异常旨在帮助应用开发者进行故障排除,而不会向最终用户显示。 异常消息未经本地化。

处理异常和错误时,可以使用异常类型本身和错误代码来区分不同的异常。 有关错误代码的列表,请参阅 Microsoft Entra 身份验证和授权错误代码

在登录体验期间,可能会遇到有关许可、条件访问(MFA、设备管理、基于位置的限制)、令牌颁发和兑换以及用户属性的错误。

以下部分提供了有关应用错误处理的更多详细信息。

MSAL.js 中的错误处理

MSAL.js 提供了一些错误对象,这些对象可对不同类型的常见错误进行抽象和分类。 它还提供用于访问具体错误详细信息的接口,例如,用于适当处理错误的错误消息。

错误对象

export class AuthError extends Error {
    // This is a short code describing the error
    errorCode: string;
    // This is a descriptive string of the error,
    // and may also contain the mitigation strategy
    errorMessage: string;
    // Name of the error class
    this.name = "AuthError";
}

通过扩展 error 类可以访问以下属性:

  • AuthError.message:与 errorMessage 相同。
  • AuthError.stack:引发的错误的堆栈跟踪。

错误类型

可用的错误类型如下:

  • AuthError:MSAL.js 库的基本 error 类,也可用于意外错误。

  • ClientAuthError:指示客户端身份验证问题的 Error 类。 来自库的大多数错误都是 ClientAuthError。 这些错误是由于在登录过程中调用 login 方法、用户取消登录等原因造成的。

  • ClientConfigurationError:扩展 ClientAuthError的错误类。 当给定的用户配置参数格式不当或缺失时,扩展发出请求之前。

  • ServerError:表示身份验证服务器所发送错误字符串的错误类。 这些错误可能包括请求格式或参数无效,或者阻止服务器对用户进行身份验证或授权的任何其他错误。

  • InteractionRequiredAuthError:扩展 ServerError 以表示需要交互式调用的服务器错误的错误类。 如果用户必须与服务器交互才能提供用于进行身份验证/授权的凭据或许可,则 acquireTokenSilent 会引发此错误。 错误代码包括 "interaction_required""login_required""consent_required"

要处理使用重定向方法(loginRedirectacquireTokenRedirect)的身份验证流中的错误,需要处理重定向承诺,它是在重定向后成功或失败时使用 handleRedirectPromise() 方法调用的,如下所示:

const msal = require('@azure/msal-browser');
const myMSALObj = new msal.PublicClientApplication(msalConfig);

// Register Callbacks for redirect flow
myMSALObj.handleRedirectPromise()
    .then(function (response) {
        //success response
    })
    .catch((error) => {
        console.log(error);
    })
myMSALObj.acquireTokenRedirect(request);

弹出体验的方法(loginPopupacquireTokenPopup)会返回承诺,因此你可以使用承诺模式(.then.catch)来处理这些错误,如下所示:

myMSALObj.acquireTokenPopup(request).then(
    function (response) {
        // success response
    }).catch(function (error) {
        console.log(error);
    });

需要交互的错误

如果尝试使用一种非交互式方法来获取令牌(如 acquireTokenSilent),则将返回错误,但 MSAL 无法以静默方式执行该操作。

可能的原因包括:

  • 需要登录
  • 需要许可
  • 需要经历多重身份验证体验。

补救措施是调用 acquireTokenPopupacquireTokenRedirect 等交互式方法:

// Request for Access Token
myMSALObj.acquireTokenSilent(request).then(function (response) {
    // call API
}).catch( function (error) {
    // call acquireTokenPopup in case of acquireTokenSilent failure
    // due to interaction required
    if (error instanceof InteractionRequiredAuthError) {
        myMSALObj.acquireTokenPopup(request).then(
            function (response) {
                // call API
            }).catch(function (error) {
                console.log(error);
            });
    }
});

条件访问和声明质询

以静默方式获取令牌时,如果你尝试访问的 API 需要条件访问声明质询(例如 MFA 策略),则应用程序可能会收到错误。

处理此错误的模式是使用 MSAL 以交互方式获取令牌。 这会提示用户,并使他们能够满足所需的条件访问策略。

在某些情况下调用需要条件访问的 API 时,API 返回的错误中可能会包含声明质询。 例如,如果条件访问策略要求使用托管设备 (Intune),则错误将类似于 AADSTS53000:需要管理你的设备才能访问此资源。 在这种情况下,可以在令牌获取调用中传递声明,使系统提示用户,以满足相应的策略。

使用 MSAL.js 以静默方式获取令牌时(使用 acquireTokenSilent),如果你尝试访问的 API 需要条件访问声明质询(例如 MFA 策略),则应用程序可能会收到错误。

处理此错误的模式是发出交互式调用(例如 acquireTokenPopupacquireTokenRedirect)以获取 MSAL.js 中的令牌,如以下示例所示:

myMSALObj.acquireTokenSilent(accessTokenRequest).then(function(accessTokenResponse) {
    // call API
}).catch(function(error) {
    if (error instanceof InteractionRequiredAuthError) {
    
        // extract, if exists, claims from the error object
        if (error.claims) {
            accessTokenRequest.claims = error.claims,
        
        // call acquireTokenPopup in case of InteractionRequiredAuthError failure
        myMSALObj.acquireTokenPopup(accessTokenRequest).then(function(accessTokenResponse) {
            // call API
        }).catch(function(error) {
            console.log(error);
        });
    }
});

以交互方式获取令牌会提示用户,并使他们能够满足所需的条件访问策略。

调用需要条件访问的 API 时,API 返回的错误中可能会包含声明质询。 在这种情况下,可以将错误中返回的声明传递给访问令牌请求对象中的 claims 参数,以满足相应的策略。

有关更多详细信息,请参阅如何在应用程序中使用启用了连续访问评估的 API

使用其他框架

生产应用无法识别将 Tauri 等工具包用于向标识平台注册的单页应用程序 (SPA)。 SPA 仅支持以 https 开头的 URL(对于生产应用)和以 http://localhost 开头的 URL(对于本地开发)。 不能将 tauri://localhost 之类的前缀用于浏览器应用。 仅移动或 Web 应用支持此格式,因为它们具有与浏览器应用不同的机密组件。

出现错误和异常后重试

调用 MSAL 时,应实现自己的重试策略。 MSAL 会对 Microsoft Entra 服务进行 HTTP 调用,有时会失败。 例如网络崩溃或服务器重载。

HTTP 429

如果服务令牌服务器 (STS) 因请求过多而重载,则将返回 HTTP 错误 429,并在 Retry-After 响应字段中提示还要多久才能重试。

后续步骤

请考虑启用 MSAL.js 中的事件日志,以帮助诊断和调试问题