The multi-tier applications involve communications at different levels. For instance, browser communicating with the web APIs and web APIs communicating with other web APIs on the behalf of the users and so on. To enable secure communication, authentication and authorization protocols might require additional handling.
It is hardly maintainable since any change in the API usage would translate to changes in the logic involved with authorized access. Consequently, there will be testing and deployment bottlenecks, especially when dealing with microservices.
To alleviate this problem, Security Token Service (STS) provides a central repository where authorization logic distributed among the different components of the application can be offloaded. Mainly, STS is responsible for issuing tokens and validating claims to resolve the issue of scoped access to resources.
Let us look at the diagram below to get the overall idea of the security token service being used.
IdentityServer4 is a frequently used STS in .NET Core applications that implement the OpenID connect and OAuth 2.0 protocols. Let us look at the diagram below to get the overall idea of the security token service being used.
NCache Details NCache with IdentityServer4 Cache Keys and Data Overview
IdentityServer with NCache
IdentityServer4 API provides the flexibility to use any external custom storage, be it a relational database, a NoSQL solution, a file system, or even an in-memory data store like NCache. For that, the authors of IdentityServer4 have implemented Entity Framework (EF) Core support for IdentityServer4 making it very easy to use any database as a storage medium for the IdentityServer4 configuration and operational data.
NCache, being a distributed, scalable in-memory key-value store, is a great fit for IdentityServer4. It can be used with IdentityServer in either of the following ways.
- NCache can be used as a cache store for IdentityServer4 configuration and operational data to speed up operations through in-memory caching as well as reduce database hits.
- NCache can be used as a configuration and persistent grant store to further increase performance by removing the bottleneck of having to get data from a disk. The in-memory contents of the cache can then be periodically persisted to disk, thus drastically decreasing the average time taken to get the data.
You can also mix and match the cache and store roles of NCache e.g. use it as a caching layer for configuration store and as a standalone store for operational data. All this is implemented using the IIdentityServerBuilder NCache extension methods used during ASP.NET Core dependency injection.
- Configuration store: a store where static data is kept which does not change as such.
- Operational store: a store where the operational data is kept on which operations are performed and is more likely to be frequently modified.
The upside of it is that you can have your data store in-memory which yields better and faster outcomes. Let us slowly sink into the detail of how it is done but there are a few prerequisites to be taken care of before getting started.
NCache Details NCache with IdentityServer4 Cache Keys and Data Overview
Pre-requisites
- .NET Core 3.0 and 3.1 SDK and runtimes.
- NCache Enterprise 5.0 SP1 or onwards running on your server(s).
- Refer to the GitHub solution to get the information on application being used. Throughout the blog, the code changes are explained according to the same application.
Scenario 1: NCache as an In-Memory IdentityServer4 Store
You can store information about the clients, API resources, identity resources, etc. (configurations), and/or persisted grants and device flow codes, etc. (operations) while using NCache as the IdentityServer store.
Now let us see where NCache fits in the picture:
In order to use NCache for the configuration and operational data:
Step 1: In the cs of your project, add the.UseStartup<StartupNCache>() method and add the following code in the StartupNcache.cs file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); var builder = services.AddIdentityServer() .AddTestUsers(TestUsers.Users) .AddNCacheConfigurationStore(options => { options.CacheId = _configuration["CacheId"]; var serverList = _configuration["Servers"].Split(',') .Select(x => x.Trim()) .ToList() .Select(y => new NCacheServerInfo(y, 9800)) .ToList(); options.ConnectionOptions = new NCacheConnectionOptions { ServerList = serverList, EnableClientLogs = true, LogLevel = NCacheLogLevel.Debug }; }) //.. rest of the code } |
Step 2: In the appsettings.json file, modify the value of the CacheId key to the name of the cache you are using. Furthermore, for the multiple Servers keys, use a comma separated list of one or more IP addresses belonging to the NCache servers making up the NCache cluster.
1 2 3 4 |
{ "CacheId": "democache", "Servers": "20.200.20.45,20.200.20.50", } |
Step 3: Run applications IdentityServer, MvcClient, Api, JavaScriptClient to see how NCache operates as an IdentityServer4 configuration and operational store after making sure that the demonstration cache used as both a configuration and operational store is running and can be connected to the IdentityServer sample application.
Scenario 2: NCache as IdentityServer4 Cache Implementation
NCache’s core functionality is to cache the data persisting in your data source for faster access and better performance. While you can use NCache as your data store, you can also use NCache between your data store and the application by caching the configuration and/or the operational data in NCache while also keeping it in the data store.
Let the figure demonstrate how NCache works as a cache with IdentityServer4.
Step 1: In order to implement NCache as a configuration store while also persisting the configuration and operational data in the data store, add UseStartup<StartupEFCore>() method and add the following code in the StartupEFCore.cs file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public void ConfigureServices(IServiceCollection services) { ... var builder = services.AddIdentityServer() .AddTestUsers(TestUsers.Users) .AddNCacheCaching(options => { options.CacheId = _configuration["CacheId"]; var serverList = _configuration["Servers"].Split(',') .Select(x => x.Trim()) .ToList() .Select(y => new NCacheServerInfo(y, 9800)) .ToList(); options.ConnectionOptions = new NCacheConnectionOptions { ServerList = serverList }; options.DurationOfBreakInSeconds = 120; }); //.. rest of the code } |
Step 2: In the appsettings.json file, modify the value of the CacheId key to the name of the cache you will be using. Furthermore, for the multiple Servers keys, use a comma separated list of one or more IP addresses belonging to the NCache servers making up the NCache cluster. Also, provide the connection string of the SQL Server.
1 2 3 4 5 6 7 8 |
{ "CacheId": "democache", "Servers": "20.200.20.45,20.200.20.50", "ConnectionStrings": { "db": "server=;database=IdentityServer4.EntityFramework;UserId=userid;Password=password;" } } |
Step 3: Run applications IdentityServer, MvcClient, Api, JavaScriptClient to see how NCache operates as a caching mechanism for the configuration store, the persisted grant store as well as the IProfileService default implementation. Make sure that the cache used as a configuration store and persisted grant store cache is running and can be connected to the IdentityServer sample application.
Conclusion
To sum it all up, IdentityServer does all the necessary authentication at each network hop in your application and NCache fits nicely to keep the configuration and operation data for faster access. Not just that NCache can also be used as your data store and store both kinds of data in-memory giving you the freedom of ridding your application of any other data source. You get all this by using the extension methods provided by NCache very easily.
NCache Details Download NCache Edition Comparison