如何解决msal.js v2.3 acquisitionTokenSilent返回空访问令牌
我正在将使用msal.js v1.3的应用程序升级到v2.3,一旦获得ID令牌,我在重新获取访问令牌时遇到问题。
我在构造函数中初始化handleRedirectPromise。然后,当用户单击登录按钮时,我调用loginRedirect并传入一个对象,该对象具有openid范围和我单独注册的api中的范围。这很好用,ID令牌又回来了,我调用了acquireTokenSilent检索我的访问令牌。我从loginRedirect调用中将具有我已注册api范围和帐户的对象传递给该函数。
问题在于,来自acquirementTokenSilent的授权响应具有空访问令牌。令牌端点的结果如下:
client_info: "xx"
id_token: "xx"
not_before: 1602895189
refresh_token: "xx"
refresh_token_expires_in: 1209600
scope: ""
token_type: "Bearer"
它没有访问令牌,但确实将令牌类型指定为Bearer
响应中没有访问令牌,并且返回的scopes属性看起来为空。这是我的代码:
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和作用域。
解决方法
acquireTokenSilent
仅在高速缓存中已存在该令牌的条目时才返回访问令牌。因此,如果由于某种原因以前从未获得过令牌(例如,通过loginRedirect
),它将无法静默地获取。
这似乎是您遇到的问题。您正在loginRequest
中混合使用不同资源的作用域,这可能会导致新版本的库出现问题(访问令牌是 per-resource-per-scope 发出的)请参阅doc。)尝试像这样修改loginRequest
对象:
private loginRequest: Msal.RedirectRequest = {
scopes: ['openid','offline_access' ],extraScopesToConsent:['https://<tenant>.onmicrosoft.com/api/read']
};
此外,建议使用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);
}
},);
};
讨论了类似的问题here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。