From b8537ff7c6302f94ed74b722a685ad378ee0b19c Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 2 Sep 2026 15:00:35 +0200 Subject: [PATCH] Added custom profile claims injector --- src/LiteCharmsSecurity.Admin.Api/Dockerfile | 4 +- src/LiteCharmsSecurity.Admin/Dockerfile | 4 +- .../Dockerfile | 4 +- .../Services/ClaimsInjectorProfileService.cs | 39 +++++++++++++++++++ .../Startup.cs | 26 +++++++------ 5 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 src/LiteCharmsSecurity.STS.Identity/Services/ClaimsInjectorProfileService.cs diff --git a/src/LiteCharmsSecurity.Admin.Api/Dockerfile b/src/LiteCharmsSecurity.Admin.Api/Dockerfile index e5d46d5..ce608b3 100644 --- a/src/LiteCharmsSecurity.Admin.Api/Dockerfile +++ b/src/LiteCharmsSecurity.Admin.Api/Dockerfile @@ -9,10 +9,10 @@ WORKDIR /app_source COPY . . -RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" --ignore-failed-sources --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" WORKDIR "/app_source/src/LiteCharmsSecurity.Admin.Api" -RUN dotnet build "LiteCharmsSecurity.Admin.Api.csproj" -c Release -o /app/build --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet build "LiteCharmsSecurity.Admin.Api.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "LiteCharmsSecurity.Admin.Api.csproj" -c Release --no-restore -o /app/publish diff --git a/src/LiteCharmsSecurity.Admin/Dockerfile b/src/LiteCharmsSecurity.Admin/Dockerfile index 23a0170..a411904 100644 --- a/src/LiteCharmsSecurity.Admin/Dockerfile +++ b/src/LiteCharmsSecurity.Admin/Dockerfile @@ -18,10 +18,10 @@ RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ COPY . . -RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" --ignore-failed-sources --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" WORKDIR "/app_source/src/LiteCharmsSecurity.Admin" -RUN dotnet build "LiteCharmsSecurity.Admin.csproj" -c Release -o /app/build --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet build "LiteCharmsSecurity.Admin.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "LiteCharmsSecurity.Admin.csproj" -c Release --no-restore -o /app/publish diff --git a/src/LiteCharmsSecurity.STS.Identity/Dockerfile b/src/LiteCharmsSecurity.STS.Identity/Dockerfile index 44e2eab..ec57dd7 100644 --- a/src/LiteCharmsSecurity.STS.Identity/Dockerfile +++ b/src/LiteCharmsSecurity.STS.Identity/Dockerfile @@ -9,10 +9,10 @@ WORKDIR /app_source COPY . . -RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" --ignore-failed-sources --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet restore "LiteCharmsSecurity.AdminUI.sln" WORKDIR "/app_source/src/LiteCharmsSecurity.STS.Identity" -RUN dotnet build "LiteCharmsSecurity.STS.Identity.csproj" -c Release -o /app/build --source "https://nexus.khongisa.co.za/repository/nuget-group/index.json" +RUN dotnet build "LiteCharmsSecurity.STS.Identity.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "LiteCharmsSecurity.STS.Identity.csproj" -c Release --no-restore -o /app/publish diff --git a/src/LiteCharmsSecurity.STS.Identity/Services/ClaimsInjectorProfileService.cs b/src/LiteCharmsSecurity.STS.Identity/Services/ClaimsInjectorProfileService.cs new file mode 100644 index 0000000..1264c8c --- /dev/null +++ b/src/LiteCharmsSecurity.STS.Identity/Services/ClaimsInjectorProfileService.cs @@ -0,0 +1,39 @@ +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Services; +using LiteCharmsSecurity.Admin.EntityFramework.Shared.Entities.Identity; +using Microsoft.AspNetCore.Identity; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; + +namespace LiteCharmsSecurity.STS.Identity.Services; + +public sealed class ClaimsInjectorProfileService(UserManager userManager) : IProfileService +{ + public Task GetProfileDataAsync(ProfileDataRequestContext context) + => GetProfileDataAsync(context, CancellationToken.None); + + public async Task GetProfileDataAsync(ProfileDataRequestContext context, CancellationToken ct) + { + var user = await userManager.GetUserAsync(context.Subject); + if (user != null && !string.IsNullOrEmpty(user.Email)) + { + context.IssuedClaims.Add(new Claim("email", user.Email)); + context.IssuedClaims.Add(new Claim("email_verified", user.EmailConfirmed ? "true" : "false")); + + if (!string.IsNullOrEmpty(user.UserName)) + { + context.IssuedClaims.Add(new Claim("preferred_username", user.UserName)); + } + } + } + + public Task IsActiveAsync(IsActiveContext context) + => IsActiveAsync(context, CancellationToken.None); + + public async Task IsActiveAsync(IsActiveContext context, CancellationToken ct) + { + var user = await userManager.GetUserAsync(context.Subject); + context.IsActive = user != null; + } +} \ No newline at end of file diff --git a/src/LiteCharmsSecurity.STS.Identity/Startup.cs b/src/LiteCharmsSecurity.STS.Identity/Startup.cs index bafa4b2..e0d7e42 100644 --- a/src/LiteCharmsSecurity.STS.Identity/Startup.cs +++ b/src/LiteCharmsSecurity.STS.Identity/Startup.cs @@ -1,24 +1,25 @@ -using System; -using System.Threading.Tasks; -using HealthChecks.UI.Client; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using IdentityModel; using Duende.IdentityServer; using Duende.IdentityServer.Configuration; +using HealthChecks.UI.Client; +using IdentityModel; using LiteCharmsSecurity.Admin.EntityFramework.Shared.DbContexts; using LiteCharmsSecurity.Admin.EntityFramework.Shared.Entities.Identity; -using Skoruba.Duende.IdentityServer.Shared.Configuration.Helpers; using LiteCharmsSecurity.STS.Identity.Configuration; using LiteCharmsSecurity.STS.Identity.Configuration.Constants; using LiteCharmsSecurity.STS.Identity.Configuration.Interfaces; using LiteCharmsSecurity.STS.Identity.Helpers; using LiteCharmsSecurity.STS.Identity.Passkeys; +using LiteCharmsSecurity.STS.Identity.Services; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Skoruba.Duende.IdentityServer.Shared.Configuration.Helpers; +using System; +using System.Threading.Tasks; namespace LiteCharmsSecurity.STS.Identity { @@ -129,7 +130,8 @@ namespace LiteCharmsSecurity.STS.Identity public virtual void RegisterAuthentication(IServiceCollection services) { services.AddAuthenticationServices(Configuration); - services.AddIdentityServer(Configuration); + services.AddIdentityServer(Configuration) + .AddProfileService(); } public virtual void RegisterAuthorization(IServiceCollection services)