Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to renew token with adal.js

Tags:

adal

adal.js

I'm using Javascript (without Angular) to add AAD authentication to my single page web app. The initial login works fine, but after an hour, the token expires, and I am unable to renew it with acquireToken. I've tried calling acquireToken when I am still logged in with my clientID and it works fine, but after the token expires, I can't renew it. It fails with "Token renewal operation failed due to timeout".

After the token expires, I ran this:

// ADALContext created from calling new AuthenticationContext
// passed in same clientID to acquire token as to create ADALContext 
ADALContext.acquireToken(clientID, function (error, token) {console.log(error, token)})

I've enabled oauth2AllowImplicitFlow in AAD.

  "keyCredentials": [],
  "knownClientApplications": [],
  "logoutUrl": null,
  "oauth2AllowImplicitFlow": true,
  "oauth2AllowUrlPathMatching": true,

Not sure what step I'm missing. Thank you!

Edit: Right after the token expires, if I run acquireToken(clientID, func), I get "User login is required". However, if I call getCachedUser, I get a user back, after which calling acquireToken returned the timeout error.

like image 395
Christina K Avatar asked Feb 14 '17 20:02

Christina K


2 Answers

I had the same issue and my fix worked. In app.component.ts, add this code to ngOnit().

this.adalService.handleWindowCallback();
this.adalService.acquireToken(this.adalService.config.loginResource).subscribe(token => {
  this.adalService.userInfo.token = token;
  if (this.adalService.userInfo.authenticated === false) {
    this.adalService.userInfo.authenticated = true;
    this.adalService.userInfo.error = '';
  }
}, error => {
  this.adalService.userInfo.authenticated = false;
  this.adalService.userInfo.error = error;
  this.adalService.login();
});

When token expires, app component gets called, and acquire token refreshes the token silently. But the this.adalService.userInfo.authenticated is still false leading to redirection or again calling login method. So manually setting it to true fixes the redirection error. this.adalService.config.loginResource this is automactically set by adal-angular itself with the resource that we need token for. Also add expireOffsetSeconds: 320, to adal configuration data settings along with

tenant: configData.adalConfig.tenant,
  clientId: configData.adalConfig.clientId,
  redirectUri: window.location.origin,
expireOffsetSeconds: 320

expireoffsetseconds invalidates the token based on the time that we specify before its actual expiry.

like image 138
Akshay Antony Avatar answered Jan 01 '23 09:01

Akshay Antony


Actually, adal for js will cache the login info into session storage or local storage in browser, depends your configuration in code. You can use chrome's develop tool to have a glance of this table: enter image description here

So the cachaed user is decoded from adal.idtoken. So you can get the cached user. And according the source code of acquireToken, it will check whether the login user is exist before renew the access token, which will raise the User login is required issue.

To bypass this issue, you can run getCachedUser() function before run acquireToken() for renewing an access token.

like image 31
Gary Liu Avatar answered Jan 01 '23 08:01

Gary Liu