0

I'm trying to implement a backend-for-frontend .NET Core 3.1 project where the tokens retrieved from Identity Server are stored in a SQL cache. The BFF is based on the implementation from SpaHost - GitHub. In the project I'm using IdentityModel.AspNetCore which should manage the token lifecycle and caching.

To store the tokens in a cache the table BffTokenCache was created with the following schema

CREATE TABLE [dbo].[BffTokenCache](
    [Id] [nvarchar](900) NOT NULL,
    [Value] [varbinary](max) NOT NULL,
    [ExpiresAtTime] [datetimeoffset](7) NOT NULL,
    [SlidingExpirationInSeconds] [bigint] NULL,
    [AbsoluteExpiration] [datetimeoffset](7) NULL
 CONSTRAINT [PK_BffTokenCache] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

In the Startup.cs class of the SpaHost project I removed

services.AddDistributedMemoryCache();

and replaced it with

services.AddDistributedSqlServerCache((options) =>
{
   options.ConnectionString = Configuration.GetConnectionString("ConnectionString_BffTokenCache");
   options.SchemaName = "dbo";
   options.TableName = "BffTokenCache";
});

To verify that the connection string and table worked for the caching service I added a line of code in the Configure() function of the Startup.cs class to get the injected IDistributedCache object and write a value to the table. That worked but when I run my project I never see any tokens getting written to the cache. I expected that as soon as a user authenticated the IdentityModel.AspNetCore library would write the token to the table.

I tried moving the services.AddDistributedSqlServerCache() line to both before and after the AddAccessTokenManagement() calls incase one would work to override the call within the AddClientAccesTokenManagement() function that does call the AddDistributedMemoryCache() but it doesn't seem to have mattered.

--UPDATE My understanding of the IdentityModel.AspNetCore library appears to be incorrect. Only Client information appears to be a cache-able object, which at this time I'm not doing. The user token data is added to a dictionary when refresh tokens are requested and NOT to the cache. So my original question is irrelevant.

cminus
  • 1,163
  • 12
  • 25
  • I'm not familiar with this scenario but testing to write a value works does not mean the real scenario works because of some difference between the tested context and the real context. In your case, I doubt that the ***value structure or format*** may matter, it should not be whatever, some warning may be printed or some log should be generated in such a case. – King King Feb 25 '21 at 20:56
  • btw, the distributed cache backs `session`, have you enabled using `session` yet? I doubt that without session enabled, that distributed cache may not be used at all (at least in your expected case). – King King Feb 25 '21 at 20:59
  • Checked the logs and there were no warnings or errors. Also, didn't have Session configured so I added it, services.AddSession(), after the AddDistributedSqlServerCache with an idle timeout of 1 minute, and added app.UseSession() after app.UseAuthentication() but still didn't see any data getting sent to the database. – cminus Feb 25 '21 at 21:27
  • Can you post the related code about manipulating cache values using an instance of IDistributedCache, and where you use them? Besides, before saving data to the Database, try to set a break point to check whether the insert item is null or not? – Zhi Lv Feb 26 '21 at 08:04
  • @ZhiLv thanks for the question. I re-investigated the library code I'm using and saw that the piece of the library applicable to my application doesn't use the caching mechanism but instead uses an internal dictionary. So the reason it wasn't working was because it should have been using the cache in the first place. – cminus Feb 26 '21 at 18:33

0 Answers0