74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
using System.Security.Claims;
|
|
using System.Net.Http.Json;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using timetracker.Shared;
|
|
|
|
namespace timetracker.Client.Services;
|
|
|
|
public class HostAuthenticationStateProvider : AuthenticationStateProvider
|
|
{
|
|
private readonly HttpClient _http;
|
|
private static readonly ClaimsPrincipal Anonymous = new(new ClaimsIdentity());
|
|
private ClaimsPrincipal? _currentUser;
|
|
|
|
public HostAuthenticationStateProvider(HttpClient http)
|
|
{
|
|
_http = http;
|
|
}
|
|
|
|
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
|
{
|
|
if (_currentUser != null)
|
|
{
|
|
return new AuthenticationState(_currentUser);
|
|
}
|
|
|
|
try
|
|
{
|
|
var response = await _http.GetAsync("api/auth/me");
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var userInfo = await response.Content.ReadFromJsonAsync<UserInfo>();
|
|
if (userInfo != null)
|
|
{
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
|
|
new Claim(ClaimTypes.Name, userInfo.Username)
|
|
};
|
|
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)
|
|
};
|
|
var identity = new ClaimsIdentity(claims, "Cookie");
|
|
_currentUser = new ClaimsPrincipal(identity);
|
|
}
|
|
else
|
|
{
|
|
_currentUser = Anonymous;
|
|
}
|
|
|
|
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser)));
|
|
}
|
|
}
|