using Blazored.LocalStorage; using Microsoft.AspNetCore.Components.Authorization; using System.Security.Claims; using System.Text.Json; namespace HotelPms.Client.Blazor.Util { public class ApiAuthenticationStateProvider : AuthenticationStateProvider { public static string? AccessToken { get; set; } private readonly ILocalStorageService _localStorage; public ApiAuthenticationStateProvider(ILocalStorageService localStorage) { _localStorage = localStorage; } public override async Task GetAuthenticationStateAsync() { var savedToken = await _localStorage.GetItemAsync("authToken"); EnvironmentSetting.Debug($"GetAuthenticationStateAsync:{savedToken}"); if (string.IsNullOrWhiteSpace(savedToken)) { return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); } if (string.IsNullOrEmpty(AccessToken)) { EnvironmentSetting.Debug($"初次认证"); //判断savedToken过期? //return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); } //_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken); AccessToken = savedToken; EnvironmentSetting.Debug($"AccessToken:{AccessToken}"); return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(savedToken), "jwt"))); } public void MarkUserAsAuthenticated(string token) { var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt")); var authState = Task.FromResult(new AuthenticationState(authenticatedUser)); NotifyAuthenticationStateChanged(authState); } public void MarkUserAsLoggedOut() { var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity()); var authState = Task.FromResult(new AuthenticationState(anonymousUser)); NotifyAuthenticationStateChanged(authState); } private IEnumerable ParseClaimsFromJwt(string jwt) { var claims = new List(); var payload = jwt.Split('.')[1]; var jsonBytes = ParseBase64WithoutPadding(payload); var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes); keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles); if (roles != null) { if (roles.ToString().Trim().StartsWith("[")) { var parsedRoles = JsonSerializer.Deserialize(roles.ToString()); foreach (var parsedRole in parsedRoles) { EnvironmentSetting.Debug("parsedRole:" + parsedRole); claims.Add(new Claim(ClaimTypes.Role, parsedRole)); } } else { EnvironmentSetting.Debug(roles.ToString()); claims.Add(new Claim(ClaimTypes.Role, roles.ToString())); } keyValuePairs.Remove(ClaimTypes.Role); } claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()))); return claims; } private byte[] ParseBase64WithoutPadding(string base64) { switch (base64.Length % 4) { case 2: base64 += "=="; break; case 3: base64 += "="; break; } return Convert.FromBase64String(base64); } } }