101 lines
3.7 KiB
C#
101 lines
3.7 KiB
C#
using System.Security.Claims;
|
|
using System.Net.Http.Json;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using timetracker.Shared;
|
|
|
|
namespace timetracker.Client.Services;
|
|
|
|
public class HostAuthenticationStateProvider : AuthenticationStateProvider
|
|
{
|
|
private readonly HttpClient _http;
|
|
private readonly PersistentComponentState _state;
|
|
private static readonly ClaimsPrincipal Anonymous = new(new ClaimsIdentity());
|
|
private ClaimsPrincipal? _currentUser;
|
|
|
|
public HostAuthenticationStateProvider(HttpClient http, PersistentComponentState state)
|
|
{
|
|
_http = http;
|
|
_state = state;
|
|
}
|
|
|
|
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
|
{
|
|
if (_currentUser != null)
|
|
{
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
|
|
if (_state.TryTakeFromJson<UserInfo>("UserInfoState", out var userInfo) && userInfo != null)
|
|
{
|
|
if (!userInfo.IsAuthenticated)
|
|
{
|
|
_currentUser = Anonymous;
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
|
|
new Claim(ClaimTypes.Name, userInfo.Username),
|
|
new Claim("IsTenantAdmin", userInfo.IsTenantAdmin ? "true" : "false"),
|
|
new Claim(ClaimTypes.Role, userInfo.IsTenantAdmin ? "TenantAdmin" : "Employee")
|
|
};
|
|
var identity = new ClaimsIdentity(claims, "Cookie");
|
|
_currentUser = new ClaimsPrincipal(identity);
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
|
|
try
|
|
{
|
|
var response = await _http.GetAsync("api/auth/me");
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var apiUserInfo = await response.Content.ReadFromJsonAsync<UserInfo>();
|
|
if (apiUserInfo != null)
|
|
{
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, apiUserInfo.Id.ToString()),
|
|
new Claim(ClaimTypes.Name, apiUserInfo.Username),
|
|
new Claim("IsTenantAdmin", apiUserInfo.IsTenantAdmin ? "true" : "false"),
|
|
new Claim(ClaimTypes.Role, apiUserInfo.IsTenantAdmin ? "TenantAdmin" : "Employee")
|
|
};
|
|
var identity = new ClaimsIdentity(claims, "Cookie");
|
|
_currentUser = new ClaimsPrincipal(identity);
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Ignore error and fall back to anonymous (e.g. server offline or network issues)
|
|
}
|
|
|
|
_currentUser = Anonymous;
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
|
|
public void NotifyUserChanged(UserInfo? userInfo)
|
|
{
|
|
if (userInfo != null)
|
|
{
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
|
|
new Claim(ClaimTypes.Name, userInfo.Username),
|
|
new Claim("IsTenantAdmin", userInfo.IsTenantAdmin ? "true" : "false"),
|
|
new Claim(ClaimTypes.Role, userInfo.IsTenantAdmin ? "TenantAdmin" : "Employee")
|
|
};
|
|
var identity = new ClaimsIdentity(claims, "Cookie");
|
|
_currentUser = new ClaimsPrincipal(identity);
|
|
}
|
|
else
|
|
{
|
|
_currentUser = Anonymous;
|
|
}
|
|
|
|
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser)));
|
|
}
|
|
}
|