msal.js v2.3 acquireTokenSilent 返回空访问令牌

afr*_*111 3 azure-ad-b2c azure-ad-msal msal.js

我正在使用 msal.js v1.3 将应用程序升级到 v2.3,并且在获取 id 令牌后检索访问令牌时遇到问题。

我在构造函数中初始化了handleRedirectPromise。然后,当用户单击登录按钮时,我调用 loginRedirect 并传入一个具有 openid 范围和来自我单独注册的 api 的范围的对象。这很有效,id 令牌返回,我调用 acquireTokenSilent 来检索我的访问令牌。我将一个包含我注册的 api 范围和帐户的对象从 loginRedirect 调用传递到此函数中。

问题是来自 acquireTokenSilent 的授权响应具有空的访问令牌。令牌端点的结果如下所示:

client_info: "xx"
id_token: "xx"
not_before: 1602895189
refresh_token: "xx"
refresh_token_expires_in: 1209600
scope: ""
token_type: "Bearer"
Run Code Online (Sandbox Code Playgroud)

它没有访问令牌,但它确实指定了令牌类型,因为Bearer 响应中没有访问令牌,并且看起来返回的范围属性为空。这是我的代码:

client_info: "xx"
id_token: "xx"
not_before: 1602895189
refresh_token: "xx"
refresh_token_expires_in: 1209600
scope: ""
token_type: "Bearer"
Run Code Online (Sandbox Code Playgroud)

为什么访问令牌没有从令牌端点返回?这与范围返回空有关吗?我尝试删除范围并放入无效条目,然后出现错误,所以我知道我的请求至少是有效的。另外,为了验证一下,我在 AAD 中有 2 个应用程序注册,一个是我为我的 spa 创建的,具有代码流,另一个是我为我的 api 创建的旧注册,具有公开的 api 和范围。

der*_*sen 5

acquireTokenSilent仅当缓存中已存在该令牌的条目时才会返回访问令牌。因此,如果由于某种原因之前从未获得过令牌(loginRedirect例如通过),它将无法静默地获取它。

这似乎是你的情况的问题。您在 中混合了不同资源的作用域loginRequest,这可能会导致新版本的库中出现问题(访问令牌是按每个资源每个范围发出的。有关更多信息,请参阅此文档)尝试修改您的loginRequest对象,例如这:

  private loginRequest: Msal.RedirectRequest = {
       scopes: ['openid',  'offline_access' ],
       extraScopesToConsent:['https://<tenant>.onmicrosoft.com/api/read']

   };
Run Code Online (Sandbox Code Playgroud)

另外,推荐的使用模式是,如果由于某种原因失败,acquireTokenSilent您应该回退到交互式方法(例如acquireTokenRedirect) 。acquireTokenSilent

所以我将其修改为:

    this.aquireSilent = (request: Msal.SilentRequest): Promise<Msal.AuthenticationResult> => {
        return _this.msalInstance.acquireTokenSilent(request).then(
            access_token => {
                 // fallback to interaction when response is null
                 if (access_token === null) {
                   return _this.msalInstance.acquireTokenRedirect(request);
                 }
                _this.cacheExpiration(access_token.expiresOn);
                _this.isLoggedIn$.next(true);
                return access_token;
            },
            function (reason) {          
               if (reason instanceof msal.InteractionRequiredAuthError) {
                  // fallback to interaction when silent call fails
                  return _this.msalInstance.acquireTokenRedirect(request);
               } else {
                  console.warn(reason);   
               }
            },
        );
    };
Run Code Online (Sandbox Code Playgroud)

这里讨论了类似的问题