|
|
|
@ -1,25 +1,83 @@ |
|
|
|
|
using Blazored.LocalStorage; |
|
|
|
|
using FluentBlazorAuth.Models; |
|
|
|
|
using FluentBlazorAuth.Services; |
|
|
|
|
using Microsoft.AspNetCore.Components.Authorization; |
|
|
|
|
using Microsoft.AspNetCore.Http; |
|
|
|
|
using System.Security.Claims; |
|
|
|
|
using System.Text.Json; |
|
|
|
|
|
|
|
|
|
namespace FluentBlazorAuth.States |
|
|
|
|
{ |
|
|
|
|
public class CustomAuthenticationStateProvider : AuthenticationStateProvider |
|
|
|
|
{ |
|
|
|
|
private readonly ILocalStorageService _localStorage; |
|
|
|
|
private readonly IUserAccountService _userAccountService; |
|
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor; |
|
|
|
|
|
|
|
|
|
public CustomAuthenticationStateProvider(ILocalStorageService localStorage) |
|
|
|
|
private const string UserCookieKey = "UserCookie"; |
|
|
|
|
private UserAccount? _currentUser; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public CustomAuthenticationStateProvider(IUserAccountService userAccountService, IHttpContextAccessor httpContextAccessor) |
|
|
|
|
{ |
|
|
|
|
_userAccountService = userAccountService; |
|
|
|
|
_httpContextAccessor = httpContextAccessor; |
|
|
|
|
|
|
|
|
|
LoadUserFromCookie(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override Task<AuthenticationState> GetAuthenticationStateAsync() |
|
|
|
|
{ |
|
|
|
|
_localStorage = localStorage; |
|
|
|
|
var identity = _currentUser != null |
|
|
|
|
? new ClaimsIdentity(new[] |
|
|
|
|
{ |
|
|
|
|
new Claim(ClaimTypes.Name, _currentUser.UserName), |
|
|
|
|
new Claim(ClaimTypes.Role, _currentUser.Role) |
|
|
|
|
}, "apiauth_type") |
|
|
|
|
: new ClaimsIdentity(); |
|
|
|
|
|
|
|
|
|
var claimPrincipal = new ClaimsPrincipal(identity); |
|
|
|
|
|
|
|
|
|
return Task.FromResult(new AuthenticationState(claimPrincipal)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override async Task<AuthenticationState> GetAuthenticationStateAsync() |
|
|
|
|
public void MarkUserAsAuthenticated(UserAccount userAccount) |
|
|
|
|
{ |
|
|
|
|
var token = await _localStorage.GetItemAsync<string>("authToken"); |
|
|
|
|
if (string.IsNullOrWhiteSpace(token)) |
|
|
|
|
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); |
|
|
|
|
_currentUser = userAccount; |
|
|
|
|
if (_currentUser != null) |
|
|
|
|
{ |
|
|
|
|
SaveUserCookie(); |
|
|
|
|
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
public void MarkUserAsLoggedOut() |
|
|
|
|
{ |
|
|
|
|
_currentUser = null; |
|
|
|
|
RemoveUserCookie(); |
|
|
|
|
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void LoadUserFromCookie() |
|
|
|
|
{ |
|
|
|
|
if (_httpContextAccessor.HttpContext?.Request.Cookies.TryGetValue(UserCookieKey, out var jsonUser) == true) |
|
|
|
|
{ |
|
|
|
|
_currentUser = JsonSerializer.Deserialize<UserAccount>(jsonUser); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void SaveUserCookie() |
|
|
|
|
{ |
|
|
|
|
_currentUser.Password = null; |
|
|
|
|
var jsonUser = JsonSerializer.Serialize(_currentUser); |
|
|
|
|
_httpContextAccessor.HttpContext?.Response.Cookies.Append(UserCookieKey, jsonUser, new CookieOptions |
|
|
|
|
{ |
|
|
|
|
HttpOnly = true, |
|
|
|
|
Expires = DateTimeOffset.Now.AddMinutes(5) |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void RemoveUserCookie() |
|
|
|
|
{ |
|
|
|
|
_httpContextAccessor.HttpContext?.Response.Cookies.Delete(UserCookieKey); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|