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;
using DigitalData.UserManager.Application.DTOs.User; using DigitalData.UserManager.Application.DTOs.User;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using NLog; using NLog;
using NLog.Web; using NLog.Web;
using System.Security.Claims;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Logging initialized."); logger.Info("Logging initialized.");
@@ -45,19 +45,30 @@ try
builder.Services.AddAuthService(config); builder.Services.AddAuthService(config);
builder.Services.AddRSAPool(config.GetSection("CryptParams")); builder.Services.AddRSAPool(config.GetSection("CryptParams"));
builder.Services.AddJwtSignatureHandler<Consumer>(api => new Dictionary<string, object> builder.Services.AddJwtSignatureHandler<Consumer>(api => new Dictionary<string, object>
{ {
{ JwtRegisteredClaimNames.Sub, api.Id }, { JwtRegisteredClaimNames.Sub, api.Id },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() } { JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
}); });
builder.Services.AddJwtSignatureHandler<UserReadDto>(user => new Dictionary<string, object>
{ 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.Sub, user.Id },
{ JwtRegisteredClaimNames.UniqueName, user.Username }, { JwtRegisteredClaimNames.UniqueName, user.Username },
{ JwtRegisteredClaimNames.Email, user.Email ?? string.Empty }, { JwtRegisteredClaimNames.Email, user.Email ?? string.Empty },
{ JwtRegisteredClaimNames.GivenName, user.Prename ?? string.Empty }, { JwtRegisteredClaimNames.GivenName, user.Prename ?? string.Empty },
{ JwtRegisteredClaimNames.FamilyName, user.Name ?? string.Empty }, { JwtRegisteredClaimNames.FamilyName, user.Name ?? string.Empty },
{ JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() } { JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
}); };
if (commonUserRoles.Length > 0)
claims.Add(ClaimTypes.Role, commonUserRoles);
return claims;
});
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions")); builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
builder.Services.AddSignalR(); builder.Services.AddSignalR();