msal.js v2.3 acquisitionTokenSilent返回空访问令牌 [英] msal.js v2.3 acquireTokenSilent returning empty access token

查看:73
本文介绍了msal.js v2.3 acquisitionTokenSilent返回空访问令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将使用msal.js v1.3的应用程序升级到v2.3,一旦获得ID令牌,我在重新获取访问令牌时遇到问题.

I am upgrading an app using msal.js v1.3 to v2.3 and I'm having a problem retreiving the access token once I get my id token.

我在构造函数中初始化handleRedirectPromise.然后,当用户单击登录按钮时,我调用loginRedirect并传入一个对象,该对象具有openid范围和我单独注册的api的范围.这很好用,ID令牌又回来了,我调用了acquireTokenSilent检索我的访问令牌.我从loginRedirect调用中将一个具有我已注册api范围和帐户的对象传递给该函数.

I initialize the handleRedirectPromise in my constructor. Then, when the user clicks the login button, I call loginRedirect and pass in an object that has the openid scope and the scope from my separately registered api. This works well, the id token comes back and I call acquireTokenSilent to retreive my access token. I pass an object that has my registered api's scope and account from the loginRedirect call into this function.

问题在于,来自acquirementTokenSilent的授权响应具有空访问令牌.令牌端点的结果如下:

The problem is that the authorization response from the acquireTokenSilent has an empty access token. The result from the token endpoint looks like:

client_info: "xx"
id_token: "xx"
not_before: 1602895189
refresh_token: "xx"
refresh_token_expires_in: 1209600
scope: ""
token_type: "Bearer"

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

It doesn't have an access token, but it does specifiy the token type as Bearer There is no access token in the response and it looks like the scopes property returning is empty. Here is my code:

    private msalConfig: Msal.Configuration = {
        auth: {
            clientId: environment.clientID,
            authority: 'https://<tenant>.b2clogin.com/<tenant>.onmicrosoft.com/B2C_1_DefaultSignInSignUp',
            knownAuthorities: ['<tenant>.b2clogin.com'],
            navigateToLoginRequestUrl: true, 
        },
        cache: {
            cacheLocation: 'sessionStorage',
            storeAuthStateInCookie: false, 
        }
    };
    private loginRequest: Msal.RedirectRequest = {
        scopes: ['openid' ,  'offline_access', 'https://<tenant>.onmicrosoft.com/api/read' ] 
    };

    private accessTokenRequest: Msal.SilentRequest = {
        scopes:  ['https://<tenant>.onmicrosoft.com/api/read'] ,
        account: null
        
    };
 constructor() {
        const _this = this;
        this.msalInstance = new Msal.PublicClientApplication(this.msalConfig);
        this.aquireSilent = (request: Msal.SilentRequest): Promise<Msal.AuthenticationResult> => {
            return _this.msalInstance.acquireTokenSilent(request).then(
                access_token => {
                    _this.cacheExpiration(access_token.expiresOn);
                    _this.isLoggedIn$.next(true);
                    return access_token;
                },
                function (reason) {
                    console.error(reason);
                },
            );
        };

        this.msalInstance
            .handleRedirectPromise()
            .then((tokenResponse: Msal.AuthenticationResult) => {
                if (tokenResponse !== null) {
                    const id_token = tokenResponse.idToken;
                    const currentAccounts = this.msalInstance.getAllAccounts()
                    this.accessTokenRequest.account = currentAccounts[0];
                    this.aquireSilent(this.accessTokenRequest)
                } 
            })
            .catch(error => {
                console.error(error);
            });
    }

    public login() {
        this.msalInstance.loginRedirect(this.loginRequest);
    }

为什么访问令牌没有从令牌端点返回?它是否与返回空的作用域有关?我尝试删除范围并放入无效条目,并引发错误,所以我知道发出的请求至少有效.另外,为验证起见,我在AAD中有2个应用程序注册,一个是为我的spa创建的具有代码流的注册,另一个是我的较早注册,我的api具有公开的api和作用域.

Why is the access token not coming back from the token endpoint? Does it have to do with the scopes returning empty? I tried removing the scopes and putting in invalid entries and an error gets raised so I know my request going out is at least valid. Also, just to verify, I have 2 app registrations in AAD, one I created for my spa that has code flow and my older registration I have for my api with an exposed api and scope.

推荐答案

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

acquireTokenSilent will return an access token only if there is already an entry for that token in the cache. So if for some reason the token was never obtained previously (via loginRedirect, for instance), it will not be able to acquire it silently.

这似乎是您遇到的问题.您在 loginRequest 中混合了不同资源的作用域,这可能在新版本的库中引起了问题(访问令牌是 per-resource-per-scope(s).请参见

That seems to be the issue in your case. You are mixing scopes for different resources in your loginRequest, and that's perhaps causing the issue in the new version of the library (access tokens are issued per-resource-per-scope(s). See this doc for more) Try modifying your loginRequest object like this:

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

   };

此外,推荐的与 acquireTokenSilent 结合使用的模式是,如果 acquireTokenSilent ,则应使用交互式方法(例如, acquireTokenRedirect ).由于某种原因而失败.

Also, the recommended pattern of usage with acquireTokenSilent is that you should fall back to an interactive method (e.g. acquireTokenRedirect) if the acquireTokenSilent fails for some reason.

所以我将其修改为:

    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);   
               }
            },
        );
    };

此处

这篇关于msal.js v2.3 acquisitionTokenSilent返回空访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆