Configure caching with the Auth0-aspnetcore-authentication SDK

Problem statement

We want to configure our Angular SPA with an ASPNetCore API backend to use shared storage (redis cache in most cases) for the user principal, etc. In the past, I’ve set up an implementation of ITicketStore when configuring the CookieAuthenticationOptions but I’m not certain how to configure this in your new SDK.

Solution

In the SDK we register the cookie middleware and use the default config, but you can still configure the cookie middleware the way you like. If you would like to configure Microsoft.AspNetCore.Authentication.Cookie middleware to use a session, you can configure it as such:

public void ConfigureServices(IServiceCollection services)
{
     services
               .AddAuth0WebAppAuthentication(PlaygroundConstants.AuthenticationScheme, options =>
               {
                   options.Domain = Configuration["Auth0:Domain"];
                   options.ClientId = Configuration["Auth0:ClientId"];
                   options.ClientSecret = Configuration["Auth0:ClientSecret"];
               });
     // Configure a custom ITicketStore to store the Identity Information on the server
     services.AddTransient<ITicketStore, CustomInMemoryTicketStore>();
     // Configure the Cookie Middleware to use the CustomInMemoryTicketStore
     services.AddSingleton<IPostConfigureOptions<CookieAuthenticationOptions>, ConfigureCookieAuthenticationOptions>();
}

and

public class ConfigureCookieAuthenticationOptions
  : IPostConfigureOptions<CookieAuthenticationOptions>
    {
        private readonly ITicketStore _ticketStore;

        public ConfigureCookieAuthenticationOptions(ITicketStore ticketStore)
        {
            _ticketStore = ticketStore;
        }

        public void PostConfigure(string name,
                 CookieAuthenticationOptions options)
        {
            options.SessionStore = _ticketStore;
        }
    }

Every request will then call the below TicketStore’s “RetrieveAsync” method:

public class CustomInMemoryTicketStore : ITicketStore
    {
        private readonly IMemoryCache _cache;

        public CustomInMemoryTicketStore(IMemoryCache cache)
        {
            _cache = cache;
        }

        public Task RemoveAsync(string key)
        {
            _cache.Remove(key);

            return Task.CompletedTask;
        }

        public Task<AuthenticationTicket> RetrieveAsync(string key)
        {
            var ticket = _cache.Get<AuthenticationTicket>(key);

            return Task.FromResult(ticket);
        }

        public Task RenewAsync(string key, AuthenticationTicket ticket)
        {
            _cache.Set(key, ticket);

            return Task.CompletedTask;
        }

        public Task<string> StoreAsync(AuthenticationTicket ticket)
        {
            var key = ticket.Principal.Claims
              .First(c => c.Type == "sid").Value;

            _cache.Set(key, ticket);

            return Task.FromResult(key);
        }
    }

The above TicketStore simply stores in memory but shows how you can add a session layer by configuring Microsoft.AspNetCore.Authentication.Cookies middleware.