I’ve been working on a web portal that users Azure Active Directory (AAD) for user authentication and for requesting permissions to the Azure Graph API, the code for which is based on this sample project.
This uses a library called Microsoft.Identity.Web that assists with acquiring and storing tokens, currently this library needs to be added manually but it seems like it should be deployed to NuGet soon.
The main issue I had with getting caching of tokens working as in the sample project was that although these seemed to be added initially they didn’t persist and I was receiving the following error when trying to retrieve tokens from the cache.
MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call
There’s 3 options for caching tokens in the Microsoft.Identity.Web library, Memory, Session and SQL. In Memory caching loses saved tokens each time the app is restarted as these are held in memory but the AAD login is persisted so although the user doesn’t need to login again when the app is restarted the token lookup will return nothing and the above error will be returned. The session caching doesn’t seem to actually save tokens to the session but that may be due to some weird interactions with my browser or ad blockers. The only one that worked for me was SQL caching which acted as a persistent token store.
In order to set up the SQL caching I needed to create the following tables and grant my SQL service account access to them, after that was done everything ran smoothly.
CREATE TABLE [dbo].[AppTokenCache] ( [AppTokenCacheId] INT IDENTITY(1,1) NOT NULL PRIMARY KEY, [ClientID] VARCHAR(255) NOT NULL, [CacheBits] VARBINARY(MAX) NOT NULL, [LastWrite] DATETIME NOT NULL, [RowVersion] VARBINARY(255) ) GO
CREATE TABLE [dbo].[UserTokenCache] ( [UserTokenCacheId] INT IDENTITY(1,1) NOT NULL PRIMARY KEY, [WebUserUniqueId] VARCHAR(255) NOT NULL, [CacheBits] VARBINARY(MAX) NOT NULL, [LastWrite] DATETIME NOT NULL, [RowVersion] VARBINARY(255) ) GO