Enhance JWT user claims with configurable roles

Updated Program.cs to include "CommonUserRoles" from configuration in JWT claims for users, adding them under ClaimTypes.Role if present. Also added System.Security.Claims using directive to support this change. This enables dynamic role assignment in user tokens.
This commit is contained in:
2026-02-03 13:58:32 +01:00
parent 31a371ecb9
commit ce69779c9f

View File

@@ -9,12 +9,12 @@ using DigitalData.Core.Security.Extensions;
using DigitalData.UserManager.Application;
using DigitalData.UserManager.Application.DTOs.User;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Web;
using System.Security.Claims;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Logging initialized.");
@@ -38,26 +38,37 @@ try
var config = builder.Configuration;
var apiParams = config.Get<AuthApiParams>() ?? throw new InvalidOperationException("AuthApiOptions is missing or invalid in appsettings.");
// Add services to the container.
builder.Services.Configure<BackdoorParams>(config.GetSection(nameof(BackdoorParams)));
builder.Services.Configure<AuthApiParams>(config);
builder.Services.AddAuthService(config);
builder.Services.AddRSAPool(config.GetSection("CryptParams"));
builder.Services.AddJwtSignatureHandler<Consumer>(api => new Dictionary<string, object>
{
{ JwtRegisteredClaimNames.Sub, api.Id },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
});
builder.Services.AddJwtSignatureHandler<UserReadDto>(user => new Dictionary<string, object>
{
{ JwtRegisteredClaimNames.Sub, user.Id },
{ JwtRegisteredClaimNames.UniqueName, user.Username },
{ JwtRegisteredClaimNames.Email, user.Email ?? string.Empty },
{ JwtRegisteredClaimNames.GivenName, user.Prename ?? string.Empty },
{ JwtRegisteredClaimNames.FamilyName, user.Name ?? string.Empty },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
});
{
{ JwtRegisteredClaimNames.Sub, api.Id },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
});
var commonUserRoles = config.GetSection("CommonUserRoles").Get<string[]>()?.Where(r => !string.IsNullOrWhiteSpace(r)).ToArray() ?? Array.Empty<string>();
builder.Services.AddJwtSignatureHandler<UserReadDto>(user =>
{
var claims = new Dictionary<string, object>
{
{ JwtRegisteredClaimNames.Sub, user.Id },
{ JwtRegisteredClaimNames.UniqueName, user.Username },
{ JwtRegisteredClaimNames.Email, user.Email ?? string.Empty },
{ JwtRegisteredClaimNames.GivenName, user.Prename ?? string.Empty },
{ JwtRegisteredClaimNames.FamilyName, user.Name ?? string.Empty },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
};
if (commonUserRoles.Length > 0)
claims.Add(ClaimTypes.Role, commonUserRoles);
return claims;
});
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
builder.Services.AddSignalR();