2

There seems to be no practical way of refreshing the token in implicit flow. Has anyone been able to achieve this? MS documentation suggests doing the refresh in an Iframe, looking for suggestions of what methods to cal in adal ng2 or adal js!!!

Edit: I'm using this library https://github.com/benbaran/adal-angular4

EDIT: Don't use the aforementioned library, it's a real POS

I Stand With Russia
  • 6,254
  • 8
  • 39
  • 67
  • I just explained in an answer blow how I am handling similar case with `oidc-client-js` and `IdentityServer` I think in your case It will be quite the same principal. What exactly `adal` library are you using? – angularrocks.com Aug 05 '17 at 03:48
  • @LastTribunal - did you switch libraries in the end? we had to 'hack' the source to get it to call our API but now any API call makes the entire app reload in an iframe *sigh* – Michael Harper Oct 13 '17 at 08:49
  • @MichaelHarper, i had to throw away that adal4 garbage and built my own. using adal2 as a guideline. I learned a lesson to take everything on github with a grain of salt – I Stand With Russia Oct 14 '17 at 00:02
  • @LastTribunal I think I'll have to do something similar – Michael Harper Oct 14 '17 at 07:15

3 Answers3

2

Using implicit flow you are not refreshing the current token, you need to get a new one.

Here is how I am handling that in my app:

I am using oidc-client-js (not adal js) that talks to IdentityServer. I have a token lifetime like 20 minutes. So in order to keep client authenticated for more than 20 minutes the new token has to be requested at some point. In order to do so I am checking if user is idle and when he is not, etc. based on the logic the new token can be obtained form the IdentityServer using signinSilent and automaticSilentRenew events. Refresh happening with iframe as it implemented in oidc-client-js.

UPDATE:

By looking in to adal-angular4 source you need to call acquireToken in order to renew the token. As per docs:

/**
* Acquire token from cache if not expired and available. Acquires token from iframe if expired.
* @param {string}   resource  ResourceUri identifying the target resource
* @param {requestCallback} callback
*/
acquireToken(resource: string, callback: (message: string, token: string) => any): void;

You can play with acquireToken using that example https://github.com/benbaran/adal-angular4-example use it as this.service.acquireToken(...) in home.component.ts

angularrocks.com
  • 26,767
  • 13
  • 87
  • 104
  • thanks bro. But as Vittorio mentioned, in implicit flow, this should happen automatically since adaljs intercepts all HTTP calls. Do you think the library I am using, which in only wrapping adal.js, interfering with the normal process? – I Stand With Russia Aug 05 '17 at 20:59
  • Additionally, it is not very clear why it is needed to specify resource url, since it was already known to the library, as it was able to use this uri in the first place during the original login Thanks again for your help! – I Stand With Russia Aug 05 '17 at 21:12
1

You don't need to do anything explicitly to renew tokens on ADAL js and angular. ADAL js automatically intercepts REST calls and, if the necessary token isn't present or near expiry, it will proactively renew the token in the background. It's all transparent to you, but there is no need to use refresh tokens in single page apps; the artifact representing the session with Azure AD is the cookie issued at authentication time. ADAL JS uses a hidden iframe to drive a UX-less authentication that leverages the presence of that cookie to get new tokens from Azure AD via implicit flow.

vibronet
  • 7,364
  • 2
  • 19
  • 21
  • I am not getting any transparent renewals, perhaps the library I am using is fubar – I Stand With Russia Aug 05 '17 at 04:12
  • Check out this sample: https://azure.microsoft.com/en-us/resources/samples/active-directory-angularjs-singlepageapp-dotnet-webapi/ and in particular the endpoints initialization. As long as the web API URL is saved there, you should get the auto renewal. Headsup. Some times hosting the API on the same domain as the app itself can malfunction. – vibronet Aug 05 '17 at 04:16
  • I think the problem is $httpProvider, it doesn't exist in Angular 2. – I Stand With Russia Aug 09 '17 at 02:58
  • 1
    Sorry, I forgot you are looking at angular 2. ADAL js is for Angular 1- if you are on angular 2, you need to use the lower layer of ADAL js and call acquiretokensilent yourself – vibronet Aug 09 '17 at 03:04
  • it would be nice if MS released an updated version of adal that works completely with angular 2. This has been one of most miserable dev efforts I ever experienced. PS: there is no acquiretokensilent method in adal (AFAIK) – I Stand With Russia Aug 09 '17 at 03:32
  • 1
    Sorry to read about your experience. Unfortunately you are targeting a platform we don't have a 1st party SDK for. The next stacks to target are being discussed. You are right that ADAL JS doesn't have acquiretokensilent; the idea is that every acquiretoken in ADAL JS is silent, and the interactive method is login- in the C# version it's different, hence my mistake. See https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi for an example of SPA that uses ADAL JS without Angular 1, that should help you to emulate the $http interceptor logic – vibronet Aug 09 '17 at 03:47
  • @vibronet - Could you please elaborate on what do you mean by using lower layer of ADAL js? – Nitin Rastogi Aug 19 '17 at 14:19
  • ADAL js includes two files, the core library and an angular 1 projection. If you want to use a js stack other than angular 1, you can base your code on the core part of ADAL.js. Take a look at https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi for an example. – vibronet Aug 19 '17 at 19:58
1

I also implemented ADAL js in my Angular 5 application and have implemented it the following way:

The user authenticates with AD and gets an access token with a lifetime (60 min in my case). That token is cached in browser. Everytime a request to the backend is fired, the token is taken from Cache and will be sent to the backend.

Then, there's another parameter called expireOffsetSeconds (defined on frontend in Adal config). It's set to 600 (=10 mins) for me. That means, that from minute 1 to minute 49 it takes the token from cache. In the last 10 minutes it then fires a new request to AD to renew the token.

Therefore, it is ensured that the user does not have to re-login every hour. BUT in case of inactivity the users' session automatically gets invalidated by ADAL.

Any feedback/improvements welcome :)

dave0688
  • 5,372
  • 7
  • 33
  • 64
  • are you using acquireToken to refresh the token or is it being handled automatically ? – Mrityunjay May 17 '18 at 14:54
  • I’m not actively using it. However, the Angular wrapper I’m using is actually calling acquireToken to refresh the token – dave0688 May 17 '18 at 14:57
  • Using nested controllers and having an $interval set to force refresh of the token is what I've done in the past to handle this. Just gotta wire in the active state of the interval to log in/out states. – Bon Oct 07 '18 at 20:31