Environment
- Angular 5 frontend
- AzureAD auth using Adal-Angular
Current Scenario
- User auth success and access/refresh token taken
- After some time, access token expires.
- 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