You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.4 KiB
86 lines
2.4 KiB
using System;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Net.Http.Json;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using BlazorShared.Authorization;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace BlazorAdmin;
|
|
|
|
public class CustomAuthStateProvider : AuthenticationStateProvider
|
|
{
|
|
// TODO: Get Default Cache Duration from Config
|
|
private static readonly TimeSpan UserCacheRefreshInterval = TimeSpan.FromSeconds(60);
|
|
|
|
private readonly HttpClient _httpClient;
|
|
private readonly ILogger<CustomAuthStateProvider> _logger;
|
|
|
|
private DateTimeOffset _userLastCheck = DateTimeOffset.FromUnixTimeSeconds(0);
|
|
private ClaimsPrincipal _cachedUser = new ClaimsPrincipal(new ClaimsIdentity());
|
|
|
|
public CustomAuthStateProvider(HttpClient httpClient,
|
|
ILogger<CustomAuthStateProvider> logger)
|
|
{
|
|
_httpClient = httpClient;
|
|
_logger = logger;
|
|
}
|
|
|
|
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
|
{
|
|
return new AuthenticationState(await GetUser(useCache: true));
|
|
}
|
|
|
|
private async ValueTask<ClaimsPrincipal> GetUser(bool useCache = false)
|
|
{
|
|
var now = DateTimeOffset.Now;
|
|
if (useCache && now < _userLastCheck + UserCacheRefreshInterval)
|
|
{
|
|
return _cachedUser;
|
|
}
|
|
|
|
_cachedUser = await FetchUser();
|
|
_userLastCheck = now;
|
|
|
|
return _cachedUser;
|
|
}
|
|
|
|
private async Task<ClaimsPrincipal> FetchUser()
|
|
{
|
|
UserInfo user = null;
|
|
|
|
try
|
|
{
|
|
_logger.LogInformation("Fetching user details from web api.");
|
|
user = await _httpClient.GetFromJsonAsync<UserInfo>("User");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
_logger.LogWarning(exc, "Fetching user failed.");
|
|
}
|
|
|
|
if (user == null || !user.IsAuthenticated)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var identity = new ClaimsIdentity(
|
|
nameof(CustomAuthStateProvider),
|
|
user.NameClaimType,
|
|
user.RoleClaimType);
|
|
|
|
if (user.Claims != null)
|
|
{
|
|
foreach (var claim in user.Claims)
|
|
{
|
|
identity.AddClaim(new Claim(claim.Type, claim.Value));
|
|
}
|
|
}
|
|
|
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", user.Token);
|
|
|
|
return new ClaimsPrincipal(identity);
|
|
}
|
|
}
|
|
|