I have a scenario, where 3 different types of clients (types of devices) are expected to be able to authenticate against my web app via Azure AD. However, only within the first type (normal browser from a PC environment) are users to be asked to insert their
Azure AD username and password to log in. My idea was to create some kind of process which only requires logging in with the Azure AD username and password the first time. Users would use the first type of client for first login, but the process would also
work without the username and password from then on; instead users would be able to access the system by the means of username + pin or even by smart-card login.
After some research, the 'Refresh token' term seemed to pop up very often. It seems that the more recent versions of ADAL no
longer provide the physical refresh token; so the actual refresh-token could not be saved in some database and then used when logging in from type 2 or type 3 devices. However, the same article also suggests that this Refresh token is now handled automatically
by ADAL in cache.
I also found some great sample
code that implements persisted ADAL Token Cache inside a MSSQLLocalDB database via Entity Framework.
Essentially my idea is to:
-
Use OpenIDConnect to do the authentication the first time with username and password and save the TokenCache inside the local db
-
When logging in the next time without username and password, retrieve the persisted
Token Cache from the local db And use
-
AcquireTokenSilentAsync to login, and have ADAL handle the refresh token logic for me, like it would in an in-cache memory scenario.
Now I am not sure whether my attempt at working-around this (above) is at least on the right track (guide me :) !), but I have noticed that the tenantID, SignedInUserID and UserObjectID used in the below snippet are all retrievable upon the first successful
authentication, which prompted me to at least try it out.
Dim clientcred As ClientCredential = New ClientCredential(aadClientId, aadAppKey)
Dim authenticationContext As AuthenticationContext = New AuthenticationContext(aadInstance & tenantId, New ADALTokenCache(SignedInUserID))
Dim authenticationResult As AuthenticationResult = Await authenticationContext.AcquireTokenSilentAsync(aadGraphResourceID, clientcred, New UserIdentifier(UserObjectID, UserIdentifierType.UniqueId))
Note: ADALTokenCache is the constructor of the custom ADALTokenCache class that handles persisting the TokenCache inside the local db.
So I saved these 3 values in my system database and then upon smart-card login I am retrieving them by the username, and then using AcquireTokenSilentAsync as demonstrated above.
I have implemented this solution and have some questions -
![Snippet of Authentication Result returned object.]()
1) It seems that the persisted token is retrieved from the local db, and it seems that the authenticationResult object does retrieve the correct values; access token, id token, and User Info! However, it does not seem like that authenticates me/ logs me in.
request.IsAuthenticated stays false and I am clueless at what to do next. Is the process wrong or do I need to do something more?
2) The authenticationResult seems to have an expiration date which is always 1 hour from the time of the original token creation. This seems to me like the actual Access token expiration time, but nothing related to the Refresh token expiration is visible within
any ADAL related object! So it is quite a tricky situation.
3) ADAL does say that Refresh tokens are handled in cache automatically. But is there something to be configured from the Azure AD configuration side? I have found nothing related to setting up the refresh token or its expiration details inside the Azure portal.