From 5d5b59d610a2d69baea90372e91f03688558e565 Mon Sep 17 00:00:00 2001 From: Khwezi Mngoma Date: Sat, 6 Jun 2026 16:26:27 +0200 Subject: [PATCH] Updated API to use LiteCharms Security --- .../http/{authentik => litecharms}/app.http | 4 +- .../http/litecharms/http-client.env.json | 9 ++++ ...entikSettings.cs => LiteCharmsSettings.cs} | 12 ++---- LiteCharms.Features/Extensions/Api.cs | 41 +++++++++---------- 4 files changed, 34 insertions(+), 32 deletions(-) rename LiteCharms.Features.Tests/http/{authentik => litecharms}/app.http (50%) create mode 100644 LiteCharms.Features.Tests/http/litecharms/http-client.env.json rename LiteCharms.Features/Api/Configuration/{AuthentikSettings.cs => LiteCharmsSettings.cs} (54%) diff --git a/LiteCharms.Features.Tests/http/authentik/app.http b/LiteCharms.Features.Tests/http/litecharms/app.http similarity index 50% rename from LiteCharms.Features.Tests/http/authentik/app.http rename to LiteCharms.Features.Tests/http/litecharms/app.http index 9105f67..09e5d9f 100644 --- a/LiteCharms.Features.Tests/http/authentik/app.http +++ b/LiteCharms.Features.Tests/http/litecharms/app.http @@ -1,6 +1,6 @@ ### Authentik Token Request (Service Account Explicit) -POST {{authority}} +POST {{authority}}/connect/token Content-Type: application/x-www-form-urlencoded Accept-Encoding: identity -grant_type={{grantType}}&client_id={{clientId}}&username={{username}}&password={{password}}&scope={{scope}} +grant_type={{grantType}}&client_id={{clientId}}&client_secret={{clientSecret}}&scope={{scope}} diff --git a/LiteCharms.Features.Tests/http/litecharms/http-client.env.json b/LiteCharms.Features.Tests/http/litecharms/http-client.env.json new file mode 100644 index 0000000..36d0bd1 --- /dev/null +++ b/LiteCharms.Features.Tests/http/litecharms/http-client.env.json @@ -0,0 +1,9 @@ +{ + "uat": { + "authority": "https://sts.security.khongisa.co.za", + "grantType": "client_credentials", + "clientId": "midrandbooks-api-uat", + "clientSecret": "secret_5a36d0024980544c875447a4b052938becc3fbbb10b8b2c097310c1a53ba3c0a", + "scope": "midrandbooks-api" + } +} diff --git a/LiteCharms.Features/Api/Configuration/AuthentikSettings.cs b/LiteCharms.Features/Api/Configuration/LiteCharmsSettings.cs similarity index 54% rename from LiteCharms.Features/Api/Configuration/AuthentikSettings.cs rename to LiteCharms.Features/Api/Configuration/LiteCharmsSettings.cs index db03e12..58f49bc 100644 --- a/LiteCharms.Features/Api/Configuration/AuthentikSettings.cs +++ b/LiteCharms.Features/Api/Configuration/LiteCharmsSettings.cs @@ -1,22 +1,16 @@ namespace LiteCharms.Features.Api.Configuration; -public sealed class AuthentikSettings +public sealed class LiteCharmsSettings { public string? Authority { get; set; } - public string? IntrospectionEndpoint { get; set; } - - public string? MetadataEndpoint { get; set; } - - public string? RevokationEndpoint { get; set; } - public string? ClientId { get; set; } public string? ClientSecret { get; set; } + public string? Audience { get; set; } + public string? RequiredClaimName { get; set; } public string? RequiredClaimNameValue { get; set; } - - public bool RequireHttpsMetadata { get; set; } } diff --git a/LiteCharms.Features/Extensions/Api.cs b/LiteCharms.Features/Extensions/Api.cs index 30e76da..c66b25e 100644 --- a/LiteCharms.Features/Extensions/Api.cs +++ b/LiteCharms.Features/Extensions/Api.cs @@ -1,6 +1,7 @@ using LiteCharms.Features.Abstractions; using LiteCharms.Features.Api; using LiteCharms.Features.Api.Configuration; +using Microsoft.AspNetCore.Authentication.JwtBearer; namespace LiteCharms.Features.Extensions; @@ -9,14 +10,14 @@ public static class Api public const string Books = nameof(Books); public const string Payments = nameof(Payments); - public static IServiceCollection AddAuthentikUiSecurity(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddLiteCharmsUiSecurity(this IServiceCollection services, IConfiguration configuration) { - var configSection = configuration.GetSection(nameof(AuthentikSettings)); + var configSection = configuration.GetSection(nameof(LiteCharmsSettings)); - var authOptions = new AuthentikSettings(); + var authOptions = new LiteCharmsSettings(); configSection.Bind(authOptions); - services.Configure(configSection); + services.Configure(configSection); services.AddAuthentication(options => { @@ -26,8 +27,7 @@ public static class Api .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => { - options.Authority = authOptions.Authority; - options.MetadataAddress = authOptions.MetadataEndpoint; + options.Authority = authOptions.Authority; options.ClientId = authOptions.ClientId; options.ClientSecret = authOptions.ClientSecret; @@ -54,27 +54,26 @@ public static class Api return services; } - public static IServiceCollection AddAuthentikApiSecurity(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddLiteCharmsApiSecurity(this IServiceCollection services, IConfiguration configuration) { - var configSection = configuration.GetSection(nameof(AuthentikSettings)); + var configSection = configuration.GetSection(nameof(LiteCharmsSettings)); - var authOptions = new AuthentikSettings(); + var authOptions = new LiteCharmsSettings(); configSection.Bind(authOptions); - services.Configure(configSection); + services.Configure(configSection); - services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme) - .AddOAuth2Introspection(OAuth2IntrospectionDefaults.AuthenticationScheme, options => + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { options.Authority = authOptions.Authority; - options.IntrospectionEndpoint = authOptions.IntrospectionEndpoint; - options.ClientId = authOptions.ClientId; - options.ClientSecret = authOptions.ClientSecret; - - options.NameClaimType = "sub"; - options.DiscoveryPolicy.RequireHttps = authOptions.RequireHttpsMetadata; - options.DiscoveryPolicy.ValidateEndpoints = false; - options.EnableCaching = false; + options.Audience = authOptions.Audience; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidIssuer = authOptions.Authority, + ValidateAudience = true, + ValidateIssuer = true, + }; }); if (!string.IsNullOrWhiteSpace(authOptions.RequiredClaimName) && !string.IsNullOrWhiteSpace(authOptions.RequiredClaimNameValue)) @@ -99,7 +98,7 @@ public static class Api }); }); - app.MapGet("/logout", async (HttpContext context, IHttpClientFactory httpClientFactory, IOptions settings) => + app.MapGet("/logout", async (HttpContext context, IHttpClientFactory httpClientFactory, IOptions settings) => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);