Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions Auth/LearningHub.Nhs.Auth/Helpers/InMemoryTicketStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
namespace LearningHub.Nhs.Auth.Helpers
{
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

/// <summary>
/// Defines the <see cref="InMemoryTicketStore" />.
/// </summary>
public class InMemoryTicketStore : ITicketStore
{
private readonly ConcurrentDictionary<string, AuthenticationTicket> cache;

/// <summary>
/// Initializes a new instance of the <see cref="InMemoryTicketStore"/> class.
/// The InMemoryTicketStore.
/// </summary>
/// <param name="cache">the cache.</param>
public InMemoryTicketStore(ConcurrentDictionary<string, AuthenticationTicket> cache)
{
this.cache = cache;
}

/// <summary>
/// The StoreAsync.
/// </summary>
/// <param name="ticket">The ticket.</param>
/// <returns>The key.</returns>
public async Task<string> 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;
}

/// <summary>
/// The RenewAsync.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="ticket">The ticket.</param>
/// <returns>The Task.</returns>
public Task RenewAsync(
string key,
AuthenticationTicket ticket)
{
this.cache.AddOrUpdate(
key,
ticket,
(_, _) => ticket);
return Task.CompletedTask;
}

/// <summary>
/// The RetrieveAsync.
/// </summary>
/// <param name="key">The Key.</param>
/// <returns>The Task.</returns>
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
this.cache.TryGetValue(
key,
out var ticket);
return Task.FromResult(ticket);
}

/// <summary>
/// The RemoveAsync.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>The Task.</returns>
public Task RemoveAsync(string key)
{
this.cache.TryRemove(
key,
out _);
return Task.CompletedTask;
}
}
}
10 changes: 9 additions & 1 deletion Auth/LearningHub.Nhs.Auth/ServiceCollectionExtension.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
namespace LearningHub.Nhs.Auth
{
using System;
using System.Collections.Concurrent;
using System.Security.Cryptography.X509Certificates;
using Azure.Identity;
using IdentityServer4;
using LearningHub.Nhs.Auth.Configuration;
using LearningHub.Nhs.Auth.Helpers;
using LearningHub.Nhs.Auth.Middleware;
using LearningHub.Nhs.Caching;
using LearningHub.Nhs.Models.Enums;
Expand Down Expand Up @@ -70,7 +72,13 @@ public static void ConfigureServices(this IServiceCollection services, IConfigur
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie().AddOpenIdConnect(
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.AccessDeniedPath = "/Home/AccessDenied";
options.SessionStore = new InMemoryTicketStore(new ConcurrentDictionary<string, AuthenticationTicket>());
})
.AddOpenIdConnect(
"oidc_oa",
options =>
{
Expand Down
Loading