2

I'm attempting to add caching to our IS4 implementation using their Caching methods. However, my implementation does not appear to be having any impact on the speed of login or the number of queries hitting my database per login (which I would expect caching to reduce both).

The changes I made to implement caching are as follows:

Added the following to Startup.cs ConfigureServices

Updated the services.AddIdenttiyServer() call to include the lines:

.AddInMemoryCaching()
.AddClientStoreCache<IClientStore>()
.AddResourceStoreCache<IResourceStore>()
.AddCorsPolicyCache<ICorsPolicyService>();

Updated ConfigureServices to also have the following:

services.AddScoped<ICorsPolicyService, DefaultCorsPolicyService>();
services.AddScoped<IClientStore, ClientStore>();
services.AddScoped<IResourceStore, ResourceStore>();

That appeared to be the only things I needed to implement, and while the application runs normally, the caching does not seem to be doing anything. What am I missing?

Pankwood
  • 1,799
  • 5
  • 24
  • 43
Marshall Tigerus
  • 3,675
  • 10
  • 37
  • 67

2 Answers2

4

Basically you need to do 2 things:

First implement the IClientStore:

public class ClientStore : IClientStore
{
    private readonly IClientService clientService;

    public ClientStore(IClientService clientService)
    {
        this.clientService = clientService;
    }

    public Task<Client> FindClientByIdAsync(string clientId)
    {
        var client = this.clientService.GetById(clientId);
        return Task.FromResult(client);
    }
}

The ClientService is my implementation for getting the client from the db, so there you need to put your own.

Then in the Startup.cs you need:

services.AddIdentityServer(options =>
            {
                options.Caching.ClientStoreExpiration = new TimeSpan(0, 5, 0);
            })
            .AddInMemoryCaching()
            .AddClientStoreCache<ClientStore>()
            .// More stuff that you need

This is for the Client Caching but for the Cors and the ResourceStore is quite the same.

I think that you are missing the options.Caching.ClientStoreExpiration part. Start from there.

Hope that this helps.

PS: Forgot to mention - you don't need to explicitly inject your implementation of the IClientStore. By adding it to the .AddClientStoreCache<ClientStore>() it gets injected. But (as in my example) if you have other services, used by the store, you need to inject them.

m3n7alsnak3
  • 3,026
  • 1
  • 15
  • 24
  • I've not yet been able to get this to work correctly. I retrieve the client from the context properly, but when I ToModel() it it just returns the name, not the Client model – Marshall Tigerus Jul 27 '18 at 18:27
  • I got a version of this working, and it seems to improve the speed. I'm guessing you are right that the expiration is probably the main reason for it – Marshall Tigerus Jul 27 '18 at 18:42
  • you can check that it works while debugging - attach yourself, and login from one client. You will see the first time you login, you go to the FindClientByIdAsync method. Then try again to login to the same client while still in debug, and the expiration has not passed (use incognito session for example). You will see that the FindClientByIdAsync is not hit again, for the next 'X' amount of minutes - your expiration time. I'm glad that it worked out for you – m3n7alsnak3 Jul 27 '18 at 20:25
  • the logging has confirmed that it is making far fewer DB calls than it was. – Marshall Tigerus Jul 27 '18 at 21:18
0

There is no standard way to cache users.

It caches only:

  1. Clients - AddClientStoreCache
  2. Resources - AddResourceStoreCache
  3. CorsPolicy - AddCorsPolicyCache

More details you can get from documentations

Che
  • 169
  • 8
  • The documentation is rather limited. – Marshall Tigerus Jul 27 '18 at 15:40
  • @MarshallTigerus There is everything you need in short and helpful form. If it is not enough - take a look at sources and examples [https://github.com/IdentityServer](https://github.com/IdentityServer) – Che Jul 27 '18 at 15:47
  • I've done that which is how I got where I am. I'm trying to find an official sample that uses caching to compare against what I've implemented. – Marshall Tigerus Jul 27 '18 at 15:52
  • @MarshallTigerus There is no official way to cache users as I know. – Che Jul 27 '18 at 15:55
  • The calls in question are all db queries around the clients, so clientstore should be caching them – Marshall Tigerus Jul 27 '18 at 15:58
  • @MarshallTigerus Clients is not equal to Users. Clients only represent applications that can request tokens from your identityserver. – Che Jul 27 '18 at 16:00