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.
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.
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"
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);
}
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.