diff --git a/LearningHub.Nhs.WebUI/Helpers/InMemoryTicketStore.cs b/LearningHub.Nhs.WebUI/Helpers/InMemoryTicketStore.cs
new file mode 100644
index 000000000..4d17cc5b7
--- /dev/null
+++ b/LearningHub.Nhs.WebUI/Helpers/InMemoryTicketStore.cs
@@ -0,0 +1,104 @@
+namespace LearningHub.Nhs.WebUI.Helpers
+{
+ using System;
+ using System.Collections.Concurrent;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Authentication;
+ using Microsoft.AspNetCore.Authentication.Cookies;
+
+ ///
+ /// Defines the .
+ ///
+ public class InMemoryTicketStore : ITicketStore
+ {
+ private readonly ConcurrentDictionary cache;
+
+ ///
+ /// Initializes a new instance of the class.
+ /// The InMemoryTicketStore.
+ ///
+ /// the cache.
+ public InMemoryTicketStore(ConcurrentDictionary cache)
+ {
+ this.cache = cache;
+ }
+
+ ///
+ /// The StoreAsync.
+ ///
+ /// The ticket.
+ /// The key.
+ public async Task StoreAsync(AuthenticationTicket ticket)
+ {
+ var ticketUserId = ticket.Principal.Claims.Where(c => c.Type == "sub")
+ .FirstOrDefault()
+ .Value;
+ var matchingAuthTicket = this.cache.Values.FirstOrDefault(
+ t => t.Principal.Claims.FirstOrDefault(
+ c => c.Type == "sub"
+ && c.Value == ticketUserId) != null);
+ if (matchingAuthTicket != null)
+ {
+ var cacheKey = this.cache.Where(
+ entry => entry.Value == matchingAuthTicket)
+ .Select(entry => entry.Key)
+ .FirstOrDefault();
+ this.cache.TryRemove(
+ cacheKey,
+ out _);
+ }
+
+ var key = Guid
+ .NewGuid()
+ .ToString();
+ await this.RenewAsync(
+ key,
+ ticket);
+ return key;
+ }
+
+ ///
+ /// The RenewAsync.
+ ///
+ /// The key.
+ /// The ticket.
+ /// The Task.
+ public Task RenewAsync(
+ string key,
+ AuthenticationTicket ticket)
+ {
+ this.cache.AddOrUpdate(
+ key,
+ ticket,
+ (_, _) => ticket);
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// The RetrieveAsync.
+ ///
+ /// The Key.
+ /// The Task.
+ public Task RetrieveAsync(string key)
+ {
+ this.cache.TryGetValue(
+ key,
+ out var ticket);
+ return Task.FromResult(ticket);
+ }
+
+ ///
+ /// The RemoveAsync.
+ ///
+ /// The key.
+ /// The Task.
+ public Task RemoveAsync(string key)
+ {
+ this.cache.TryRemove(
+ key,
+ out _);
+ return Task.CompletedTask;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LearningHub.Nhs.WebUI/Startup/AuthenticationConfiguration.cs b/LearningHub.Nhs.WebUI/Startup/AuthenticationConfiguration.cs
index 40caab241..bbd39d9e2 100644
--- a/LearningHub.Nhs.WebUI/Startup/AuthenticationConfiguration.cs
+++ b/LearningHub.Nhs.WebUI/Startup/AuthenticationConfiguration.cs
@@ -1,12 +1,14 @@
namespace LearningHub.Nhs.WebUI.Startup
{
using System;
+ using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using IdentityModel;
using LearningHub.Nhs.Caching;
using LearningHub.Nhs.WebUI.Configuration;
using LearningHub.Nhs.WebUI.Handlers;
+ using LearningHub.Nhs.WebUI.Helpers;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
@@ -41,6 +43,7 @@ public static void ConfigureAuthentication(this IServiceCollection services, Lea
options.SlidingExpiration = true;
options.EventsType = typeof(CookieEventHandler);
options.AccessDeniedPath = "/Home/AccessDenied";
+ options.SessionStore = new InMemoryTicketStore(new ConcurrentDictionary());
})
.AddOpenIdConnect(AuthenticationScheme, options =>
{