using System.Security.Claims; using Microsoft.AspNetCore.Components.Authorization; using ZB.MOM.WW.ScadaBridge.Security; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth; /// /// Claim-lookup helpers for the Central UI. Claim types are owned /// by (the single source of truth). These helpers /// resolve them through the JwtTokenService constants so a rename there /// propagates here instead of silently breaking ten copy-pasted call sites. /// public static class ClaimsPrincipalExtensions { /// Gets fresh mutation authority, failing closed on a mapping error. /// The authentication state provider. /// The authoritative authentication state. public static Task GetAuthoritativeStateAsync(this AuthenticationStateProvider provider) => provider is CookieAuthenticationStateProvider cookie ? cookie.GetAuthoritativeStateAsync() : provider.GetAuthenticationStateAsync(); /// Checks the current grant before invoking a directly audited application service. /// The authentication state provider. /// The role the current session must hold. /// The username of the authorized principal. public static async Task RequireRoleAsync(this AuthenticationStateProvider provider, string role) { var principal = (await provider.GetAuthoritativeStateAsync()).User; if (principal.Identity?.IsAuthenticated != true || !principal.HasClaim(JwtTokenService.RoleClaimType, role)) throw new UnauthorizedAccessException($"The current session requires the {role} role."); return principal.GetUsername(); } /// Fallback returned when no username claim is present. public const string UnknownUser = "unknown"; /// /// The audit username for , or /// when the claim is absent. /// /// The claims principal to read the username from. /// The username claim value, or if absent. public static string GetUsername(this ClaimsPrincipal principal) => principal.FindFirst(JwtTokenService.UsernameClaimType)?.Value ?? UnknownUser; /// /// The display name for , or null when /// the claim is absent. /// /// The claims principal to read the display name from. /// The display name claim value, or null if the claim is absent. public static string? GetDisplayName(this ClaimsPrincipal principal) => principal.FindFirst(JwtTokenService.DisplayNameClaimType)?.Value; /// /// Resolves the current user's audit username from the auth state provider. /// Replaces the GetCurrentUserAsync helper that was copy-pasted into /// ten components. /// /// The Blazor authentication state provider to read from. /// A task that resolves to the current user's audit username, or if not authenticated. public static async Task GetCurrentUsernameAsync( this AuthenticationStateProvider authStateProvider) { var authState = await authStateProvider.GetAuthenticationStateAsync(); return authState.User.GetUsername(); } }