Add TokenUserInfo class and extend ClaimsPrincipal with methods for user claims retrieval
This commit is contained in:
parent
b1df33dc20
commit
6bef174b3d
5 changed files with 201 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
using BMA.EHR.Domain.Shared;
|
using BMA.EHR.Domain.Extensions;
|
||||||
|
using BMA.EHR.Domain.Shared;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
|
@ -81,6 +82,20 @@ namespace BMA.EHR.Domain.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Properties "
|
||||||
|
|
||||||
|
protected string? EmpType => User.GetEmpType();
|
||||||
|
protected Guid? OrgChild1DnaId => User.GetOrgChild1DnaId();
|
||||||
|
protected Guid? OrgChild2DnaId => User.GetOrgChild2DnaId();
|
||||||
|
protected Guid? OrgChild3DnaId => User.GetOrgChild3DnaId();
|
||||||
|
protected Guid? OrgChild4DnaId => User.GetOrgChild4DnaId();
|
||||||
|
protected Guid? OrgRootDnaId => User.GetOrgRootDnaId();
|
||||||
|
protected Guid? ProfileId => User.GetProfileId();
|
||||||
|
protected string? Prefix => User.GetPrefix();
|
||||||
|
protected string? FullNameFromClaim => User.GetName();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
namespace BMA.EHR.Domain.Common
|
||||||
|
{
|
||||||
|
public class TokenUserInfo
|
||||||
|
{
|
||||||
|
// Existing properties
|
||||||
|
public string KeycloakId { get; set; } = string.Empty;
|
||||||
|
public string? PreferredUsername { get; set; }
|
||||||
|
public string? GivenName { get; set; }
|
||||||
|
public string? FamilyName { get; set; }
|
||||||
|
|
||||||
|
// New properties to add
|
||||||
|
public string? EmpType { get; set; }
|
||||||
|
public Guid? OrgChild1DnaId { get; set; }
|
||||||
|
public Guid? OrgChild2DnaId { get; set; }
|
||||||
|
public Guid? OrgChild3DnaId { get; set; }
|
||||||
|
public Guid? OrgChild4DnaId { get; set; }
|
||||||
|
public Guid? OrgRootDnaId { get; set; }
|
||||||
|
public Guid? ProfileId { get; set; }
|
||||||
|
public string? Prefix { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Claim type constants
|
||||||
|
public static class BmaClaimTypes
|
||||||
|
{
|
||||||
|
public const string EmpType = "empType";
|
||||||
|
public const string OrgChild1DnaId = "orgChild1DnaId";
|
||||||
|
public const string OrgChild2DnaId = "orgChild2DnaId";
|
||||||
|
public const string OrgChild3DnaId = "orgChild3DnaId";
|
||||||
|
public const string OrgChild4DnaId = "orgChild4DnaId";
|
||||||
|
public const string OrgRootDnaId = "orgRootDnaId";
|
||||||
|
public const string ProfileId = "profileId";
|
||||||
|
public const string Prefix = "prefix";
|
||||||
|
public const string Name = "name";
|
||||||
|
public const string GivenName = "given_name";
|
||||||
|
public const string FamilyName = "family_name";
|
||||||
|
public const string PreferredUsername = "preferred_username";
|
||||||
|
}
|
||||||
|
}
|
||||||
30
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
30
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
using BMA.EHR.Domain.Common;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace BMA.EHR.Domain.Extensions
|
||||||
|
{
|
||||||
|
public static class ClaimsPrincipalExtensions
|
||||||
|
{
|
||||||
|
public static string? GetClaimValue(this ClaimsPrincipal user, string claimType)
|
||||||
|
{
|
||||||
|
return user?.FindFirst(claimType)?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Guid? GetGuidClaim(this ClaimsPrincipal user, string claimType)
|
||||||
|
{
|
||||||
|
var value = user?.GetClaimValue(claimType);
|
||||||
|
return Guid.TryParse(value, out var guid) ? guid : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience methods for common claims
|
||||||
|
public static string? GetEmpType(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.EmpType);
|
||||||
|
public static Guid? GetOrgChild1DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild1DnaId);
|
||||||
|
public static Guid? GetOrgChild2DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild2DnaId);
|
||||||
|
public static Guid? GetOrgChild3DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild3DnaId);
|
||||||
|
public static Guid? GetOrgChild4DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild4DnaId);
|
||||||
|
public static Guid? GetOrgRootDnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgRootDnaId);
|
||||||
|
public static Guid? GetProfileId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.ProfileId);
|
||||||
|
public static string? GetPrefix(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Prefix);
|
||||||
|
public static string? GetName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -79,13 +79,39 @@ namespace BMA.EHR.Domain.Middlewares
|
||||||
GetProfileByKeycloakIdLocal? pf = null;
|
GetProfileByKeycloakIdLocal? pf = null;
|
||||||
var tokenUserInfo = await ExtractTokenUserInfoAsync(token);
|
var tokenUserInfo = await ExtractTokenUserInfoAsync(token);
|
||||||
|
|
||||||
|
// Store tokenUserInfo in HttpContext.Items for controllers to use
|
||||||
|
context.Items["TokenUserInfo"] = tokenUserInfo;
|
||||||
|
|
||||||
// ดึง keycloakId จาก JWT token
|
// ดึง keycloakId จาก JWT token
|
||||||
keycloakId = tokenUserInfo.KeycloakId;
|
keycloakId = tokenUserInfo.KeycloakId;
|
||||||
|
|
||||||
// ดึง profile จาก cache หรือ API
|
// ดึง profile จาก claims หรือ cache หรือ API
|
||||||
if (Guid.TryParse(keycloakId, out var parsedId) && parsedId != Guid.Empty)
|
if (Guid.TryParse(keycloakId, out var parsedId) && parsedId != Guid.Empty)
|
||||||
{
|
{
|
||||||
pf = await GetProfileWithCacheAsync(parsedId, token);
|
// Build profile from token claims if available
|
||||||
|
if (tokenUserInfo.OrgRootDnaId.HasValue && tokenUserInfo.ProfileId.HasValue)
|
||||||
|
{
|
||||||
|
pf = new GetProfileByKeycloakIdLocal
|
||||||
|
{
|
||||||
|
Id = tokenUserInfo.ProfileId.Value,
|
||||||
|
CitizenId = tokenUserInfo.PreferredUsername,
|
||||||
|
Prefix = tokenUserInfo.Prefix,
|
||||||
|
FirstName = tokenUserInfo.GivenName,
|
||||||
|
LastName = tokenUserInfo.FamilyName,
|
||||||
|
RootDnaId = tokenUserInfo.OrgRootDnaId,
|
||||||
|
Child1DnaId = tokenUserInfo.OrgChild1DnaId,
|
||||||
|
Child2DnaId = tokenUserInfo.OrgChild2DnaId,
|
||||||
|
Child3DnaId = tokenUserInfo.OrgChild3DnaId,
|
||||||
|
Child4DnaId = tokenUserInfo.OrgChild4DnaId,
|
||||||
|
};
|
||||||
|
Console.WriteLine($"[INFO] Using claims for profile - OrgRootDnaId: {pf.RootDnaId}, ProfileId: {pf.Id}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback to API only if critical claims are missing
|
||||||
|
Console.WriteLine("[WARN] Critical claims missing, falling back to API call");
|
||||||
|
pf = await GetProfileWithCacheAsync(parsedId, token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -649,6 +675,87 @@ namespace BMA.EHR.Domain.Middlewares
|
||||||
Console.WriteLine($"Extracted family_name: {result.FamilyName}");
|
Console.WriteLine($"Extracted family_name: {result.FamilyName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ดึง empType
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("empType", out var empTypeElement))
|
||||||
|
{
|
||||||
|
result.EmpType = empTypeElement.GetString();
|
||||||
|
Console.WriteLine($"Extracted empType: {result.EmpType}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง orgChild1DnaId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("orgChild1DnaId", out var orgChild1Element))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(orgChild1Element.GetString(), out var orgChild1Guid))
|
||||||
|
{
|
||||||
|
result.OrgChild1DnaId = orgChild1Guid;
|
||||||
|
Console.WriteLine($"Extracted orgChild1DnaId: {result.OrgChild1DnaId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง orgChild2DnaId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("orgChild2DnaId", out var orgChild2Element))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(orgChild2Element.GetString(), out var orgChild2Guid))
|
||||||
|
{
|
||||||
|
result.OrgChild2DnaId = orgChild2Guid;
|
||||||
|
Console.WriteLine($"Extracted orgChild2DnaId: {result.OrgChild2DnaId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง orgChild3DnaId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("orgChild3DnaId", out var orgChild3Element))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(orgChild3Element.GetString(), out var orgChild3Guid))
|
||||||
|
{
|
||||||
|
result.OrgChild3DnaId = orgChild3Guid;
|
||||||
|
Console.WriteLine($"Extracted orgChild3DnaId: {result.OrgChild3DnaId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง orgChild4DnaId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("orgChild4DnaId", out var orgChild4Element))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(orgChild4Element.GetString(), out var orgChild4Guid))
|
||||||
|
{
|
||||||
|
result.OrgChild4DnaId = orgChild4Guid;
|
||||||
|
Console.WriteLine($"Extracted orgChild4DnaId: {result.OrgChild4DnaId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง orgRootDnaId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("orgRootDnaId", out var orgRootElement))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(orgRootElement.GetString(), out var orgRootGuid))
|
||||||
|
{
|
||||||
|
result.OrgRootDnaId = orgRootGuid;
|
||||||
|
Console.WriteLine($"Extracted orgRootDnaId: {result.OrgRootDnaId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง profileId
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("profileId", out var profileIdElement))
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(profileIdElement.GetString(), out var profileIdGuid))
|
||||||
|
{
|
||||||
|
result.ProfileId = profileIdGuid;
|
||||||
|
Console.WriteLine($"Extracted profileId: {result.ProfileId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง prefix
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("prefix", out var prefixElement))
|
||||||
|
{
|
||||||
|
result.Prefix = prefixElement.GetString();
|
||||||
|
Console.WriteLine($"Extracted prefix: {result.Prefix}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ดึง name
|
||||||
|
if (jsonDoc.RootElement.TryGetProperty("name", out var nameElement))
|
||||||
|
{
|
||||||
|
result.Name = nameElement.GetString();
|
||||||
|
Console.WriteLine($"Extracted name: {result.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -767,14 +874,6 @@ namespace BMA.EHR.Domain.Middlewares
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model classes
|
// Model classes
|
||||||
public class TokenUserInfo
|
|
||||||
{
|
|
||||||
public string KeycloakId { get; set; } = string.Empty;
|
|
||||||
public string? PreferredUsername { get; set; }
|
|
||||||
public string? GivenName { get; set; }
|
|
||||||
public string? FamilyName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GetProfileByKeycloakIdLocal
|
public class GetProfileByKeycloakIdLocal
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,13 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (UserId != null || UserId != "")
|
// First try to get from claims
|
||||||
|
var ocIdFromClaims = OrgRootDnaId;
|
||||||
|
if (ocIdFromClaims.HasValue && ocIdFromClaims.Value != Guid.Empty)
|
||||||
|
return ocIdFromClaims.Value;
|
||||||
|
|
||||||
|
// Fallback to API call for backward compatibility
|
||||||
|
if (UserId != null && UserId != "")
|
||||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||||
else
|
else
|
||||||
return Guid.Empty;
|
return Guid.Empty;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue