2

Environment

  • Angular 5 frontend
  • AzureAD auth using Adal-Angular

Current Scenario

  1. User auth success and access/refresh token taken
  2. After some time, access token expires.
  3. On subsequent request, user is redirected back to Azure login page and then redirected back to app configured home page. Due to redirection involved, user loses all work on current page. User has to restart the whole workflow and reach back to the original requesting page again.

Requirement

Upon expiration, the refresh should have been silently done without any explicit action on user's part. User stays wherever they were and continue working after the token refresh completes.

Code

Adal.service.ts

public get accessToken() {
    return this.context.getCachedToken(this.configService.getAdalConfig.clientId);
}

public get graphAccessToken() {
    return  sessionStorage[new AppConstants().User_Graph_Token];
}

public retrieveTokenForGraphAPI() {
    this.context.acquireToken('https://graph.microsoft.com', function (error, id_token) {

        if (error || !id_token) {
            console.log('ADAL error occurred: ' + error);
        } else {
            // Store token in sessionStorage
            sessionStorage[new AppConstants().User_Graph_Token] = id_token;
            return;
        }
    }.bind(this)
    );
}

OAuth.callback.component.ts

export class OAuthCallbackComponent implements OnInit {

ngOnInit() {
    if (!this.adalService.userInfo) {
        console.log('oauthCallBack::User info not found, redirecting to login');
        this.router.navigate(['loginKey']);
    } else {
        if (!this.adalService.graphAccessToken) {
            this.adalService.retrieveTokenForGraphAPI();
        }
        this.router.navigate([appConstants.App_Home_Page_URL]);
    }

Graph token consumer

Somewhere in this, it detects that the token is expired and then redirect to login page (which takes in cached params). The redirection looses out on application's workflow context hence hampering user's work

if (!this.adalService.isAuthenticated) {
    this.adalService.login();
}
const bearer = this.adalService.graphAccessToken;

// Now hit graph client
const client = MicrosoftGraphClient.Client.init({
      authProvider: (done) => {
           done(null, bearer); //first parameter takes an error if you can't get an access token
      }
});

Let me know if any other config/code details are required.

(Should instead of saving the token in session explicitly, I call the "retrieveTokenForGraphAPI" only, which can take care of getting it from its own cache or iframe as required ?)

Any suggestions for improved approach/design/code are welcome

NitinSingh
  • 2,029
  • 1
  • 15
  • 33
  • Yeah acquireAccessToken should get it invisibly via an iframe if possible. Can you see that at all in your Network tab of F12 tools? As long as the user has an active session with Azure AD, you should be able to get a new access token. – juunas Jul 12 '18 at 10:15
  • I am getting redirected to login screen as soon as Client detects that the token is expired, and then browser does auto-login (maybe as the credentials are saved and its set to remember the auth). Just that the workflow is disrupted – NitinSingh Jul 12 '18 at 10:23
  • Yeah, ADAL.JS should automatically get the token in the background without the redirect. The reason you go back to the app straight away is because the user still has an active session with Azure AD (remember it's a single sign-on system). – juunas Jul 12 '18 at 10:58
  • Did you manage to solve this? I'm having the same issue – brechtvhb Jun 28 '19 at 06:49

1 Answers1

1

Until the time a user is logged in and there is a valid session cookie present, ADAL will renew the expired token or about to expire tokens. From a user perspective, this renewal is happening in the backend and it should appear to them that the token never really expired as long as a valid session with AAD exists. I don't think there is much difference in renewing the token before it expires or after as long as there is a token available that can be served up to the protected API.

When user logs in, AAD sets a cookie. As long as that cookie is valid, ADAL can renew token silently whenever its needed. Programmatically, you can call aquireToken api to renew the token.

Also check if you have oauth2AllowImplicitFlow set to true in manifest. This might help: http://stackoverflow.com/questions/29326918/adal-js-response-type-token-is-not-supported

Mohit_Garg
  • 892
  • 5
  • 8
  • Where in the [adal.js](https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js) does automatic renewal happen? Not seeing it. Seeing only programmatic (acquireToken) and renews with a token has expired. – Matthew Campbell May 25 '20 at 14:16