Implement a distributed token cache for ASP.NET Core apps with Azure Cosmos DB

christosmatskas

Christos Matskas

Posted on July 28, 2020

Implement a distributed token cache for ASP.NET Core apps with Azure Cosmos DB

On a previous blog post we examined the steps necessary to add authentication to a Blazor Server app using the latest Microsoft.Identity.Web library. Everything worked as expected and we were able to authenticate against Azure AD, acquire an access token and retrieve data from Microsoft Graph. However, there is one small issue with the current implementation of our code. Our token cache is configured to run in memory. This is great for quickly testing the app but presents a few issues once we decide to deploy and run the app in production. The app can’t scale as the token cache is only available to the local instance and if, for whatever reason, the app restarts, all tokens in cache will be wiped out along with our cache.

Prerequisites

You need to have the following installed or available to you

  • An Azure AD tenant
  • .NET Core 3.1 or later
  • An Azure Cosmos DB instance or the local emulator
  • Visual Studio 2019 or Visual Studio Code

Implementing a distributed cache

Luckily for us, the Microsoft.Identity.Web library comes with built-in support for distributed caches. In fact, it only takes one line of code to configure it. This makes it extremely straightforward to create a robust solution right out of the box. The official documentation provides the following options for setting up a distributed cache:

  • SQL Server
  • Redis Cache
  • NCache

However, since all these cache providers implement the IDistributedCache interface, my assumption is that any provider that implements that same interface can be used with Microsoft.Identity.Web. And as luck will have it, there is already a provider for Cosmos DB (in preview) that implements this interface. Therefore, my assumption is that using this, our application should work straight out of the box without any code changes. Let’s do it!

First, we need to install the appropriate NuGet package. Use the option that works best for you (CLI, PowerShell, Package Manager etc.) to install the Microsoft.Extensions.Caching.Cosmos package

NuGet install

With the NuGet package installed, we need to edit the appsettings.json file and add the following parameters that will be used to instantiate our Cosmos DB cache which runs locally via the emulator:



"CosmosCacheContainer": "TokenCache",
"CosmosCacheDatabase": "BlazorCache",
"CosmosConnectionString": “AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",


Enter fullscreen mode Exit fullscreen mode

NOTE: note that the AccountKey on the connection string is a well know key that is common for anyone using the emulator, hence the reason I didn’t omit it here. #security

The one last thing we need to do is update our middleware code in Startup.cs to register the Cosmos DB cache and make it available to our authentication middleware. Paste the following code:



services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
    cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
    cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
    cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
    cacheOptions.CreateIfNotExists = true;
});

services.AddMicrosoftWebAppAuthentication(Configuration)
    .AddMicrosoftWebAppCallsWebApi(Configuration, new string[] { "User.Read", "Mail.Read" })
.AddDistributedTokenCaches();


Enter fullscreen mode Exit fullscreen mode

Running the code again, we can see that upon authentication, our Cosmos DB cache gets populated with our token information that can be used later by our app to retrieve the data from MS Graph:

CosmosDB cache

Video recording

There is also a video recording where we (Christos and JP) show you how we put this all together live on Twitch!

Twitch stream

The Identity Dev Advocates team streams on Tuesdays at 7am PT and Thursdays at 8am PT on Twitch. We cover all things identity and we like to bring guests and customers on the air to learn how they use our tools and platform to build their solutions.

If you want to get involved or have any questions make sure to reach out to Christos Matskas or JP

Summary

As you can see, the latest Microsoft.Identity.Web makes it very easy to work with distributed caches in a ‘plug-n-play’ mode. And, as long as, a cache provider implements the IDistributedCache interface, you can use any custom cache with your ASP.NET Core app.

💖 💪 🙅 🚩
christosmatskas
Christos Matskas

Posted on July 28, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related