diff --git a/phronCare.API/Controllers/TestController.cs b/phronCare.API/Controllers/TestController.cs index 2235151..f99a278 100644 --- a/phronCare.API/Controllers/TestController.cs +++ b/phronCare.API/Controllers/TestController.cs @@ -15,7 +15,7 @@ namespace phronCare.API.Controllers [HttpGet("empleados")] public IEnumerable GetEmpleados() { - return new List { "Leandro", "Griselda", "Agustin","Victoria" }; + return new List { "SOS USUARIO", "Griselda", "Agustin","Victoria" }; } [Authorize (Roles ="Admin")] @@ -23,7 +23,7 @@ namespace phronCare.API.Controllers public IEnumerable GetAdministradores() { - return new List { "Leandro", "Griselda", "Agustin", "Victoria" }; + return new List { "SOS ADMINISTRADOR", "Griselda", "Agustin", "Victoria" }; } } } diff --git a/phronCare.UIBlazor/Pages/Accounts/Users.razor b/phronCare.UIBlazor/Pages/Accounts/Users.razor index bf407b0..bf1a8d7 100644 --- a/phronCare.UIBlazor/Pages/Accounts/Users.razor +++ b/phronCare.UIBlazor/Pages/Accounts/Users.razor @@ -69,6 +69,7 @@ else try { var response = await _httpClient.GetAsync("/api/Account/GetAllUsers"); + Console.WriteLine(token.token); if (response.IsSuccessStatusCode) { var jsonResponse = await response.Content.ReadAsStringAsync(); diff --git a/phronCare.UIBlazor/Services/Authorization/CustomAuthorizationProvider.cs b/phronCare.UIBlazor/Services/Authorization/CustomAuthorizationProvider.cs index b46ddf9..115d95b 100644 --- a/phronCare.UIBlazor/Services/Authorization/CustomAuthorizationProvider.cs +++ b/phronCare.UIBlazor/Services/Authorization/CustomAuthorizationProvider.cs @@ -7,47 +7,72 @@ using phronCare.UIBlazor.Extensions; namespace phronCare.UIBlazor.Services.Authorization { - public class CustomAuthorizationProvider: AuthenticationStateProvider,ILoginService + public class CustomAuthorizationProvider : AuthenticationStateProvider, ILoginService { private readonly IJSExtensions js; private readonly HttpClient httpClient; public static readonly string TOKENKEY = "phronCareTokenKey"; private AuthenticationState Anonimo => new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); - public CustomAuthorizationProvider(IJSRuntime _js, HttpClient httpClient) //Constructor + + public CustomAuthorizationProvider(IJSRuntime _js, HttpClient httpClient) { this.httpClient = httpClient; js = new IJSExtensions(_js); } - public async override Task GetAuthenticationStateAsync() + + public override async Task GetAuthenticationStateAsync() { var token = await js.GetFromLocalStorage(TOKENKEY); - if (string.IsNullOrEmpty(token)) + + if (string.IsNullOrWhiteSpace(token) || !IsJwtFormat(token)) { + await js.RemoveItem(TOKENKEY); return Anonimo; } + return BuildAuthenticationState(token); } + private AuthenticationState BuildAuthenticationState(string token) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"))); } + public async Task GetTokenData() { - var token = await js.GetFromLocalStorage(TOKENKEY); - //TokenData result = JsonSerializer.Deserialize(token); - //return result; - TokenData? result = JsonSerializer.Deserialize(token); + var authState = await GetAuthenticationStateAsync(); + var user = authState.User; - if (result == null) + if (user.Identity is null || !user.Identity.IsAuthenticated) + throw new InvalidOperationException("Usuario no autenticado."); + + var tokenString = await js.GetFromLocalStorage(TOKENKEY); // <-- ACA RECUPERAMOS EL JWT + + return new TokenData { - // Maneja el caso en el que la deserialización falla y devuelve null - // Puedes lanzar una excepción, retornar un valor predeterminado, o manejar el error de otra forma - throw new InvalidOperationException("El token no se pudo deserializar en un objeto TokenData."); - } - - return result; + userName = user.Identity.Name ?? string.Empty, + role = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value ?? string.Empty, + token = tokenString ?? string.Empty, // <-- ACA SETEAMOS el token string + expiryTimeStamp = DateTime.UtcNow + }; } + //public async Task GetTokenData() + //{ + // var authState = await GetAuthenticationStateAsync(); + // var user = authState.User; + + // if (user.Identity is null || !user.Identity.IsAuthenticated) + // throw new InvalidOperationException("Usuario no autenticado."); + + // return new TokenData + // { + // userName = user.Identity.Name ?? string.Empty, + // role = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value ?? string.Empty, + // expiryTimeStamp = DateTime.UtcNow // Opcional: ajustar si extraes exp claim + // }; + //} + public async Task Login(string token) { await js.RemoveItem(TOKENKEY); @@ -55,39 +80,14 @@ namespace phronCare.UIBlazor.Services.Authorization var authState = BuildAuthenticationState(token); NotifyAuthenticationStateChanged(Task.FromResult(authState)); } + public async Task Logout() { httpClient.DefaultRequestHeaders.Authorization = null; await js.RemoveItem(TOKENKEY); NotifyAuthenticationStateChanged(Task.FromResult(Anonimo)); } - //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) - // { - // claims.Add(new Claim(ClaimTypes.Role, parsedRole)); - // } - // } - // else - // { - // 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 IEnumerable ParseClaimsFromJwt(string jwt) { var claims = new List(); @@ -97,8 +97,7 @@ namespace phronCare.UIBlazor.Services.Authorization if (keyValuePairs != null && keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles)) { - // Verificamos si roles no es null y lo convertimos a string de manera segura - string rolesString = roles?.ToString() ?? string.Empty; // Aquí usamos un valor por defecto si es null + var rolesString = roles?.ToString() ?? string.Empty; if (!string.IsNullOrEmpty(rolesString)) { @@ -126,6 +125,7 @@ namespace phronCare.UIBlazor.Services.Authorization return claims; } + private byte[] ParseBase64WithoutPadding(string base64) { switch (base64.Length % 4) @@ -135,12 +135,18 @@ namespace phronCare.UIBlazor.Services.Authorization } return Convert.FromBase64String(base64); } + + private bool IsJwtFormat(string token) + { + return token?.Count(c => c == '.') == 2; + } + public class TokenData { public string userName { get; set; } = string.Empty; - public string token { get; set; } = string.Empty; public string role { get; set; } = string.Empty; + public string token { get; set; } = string.Empty; public DateTime expiryTimeStamp { get; set; } } } -} \ No newline at end of file +}