Ein erneutes Laden der Seite lässt sich nicht vermeiden. Dies muss auch gewährleistet sein, daher das Cookie.
Ich habe hier bereits nach einem CustomAuthStateProvider gefragt, aber leider will das JavaScript nicht in der aktuellen Anwendung laden. Es befindet sich in App.razor. Können Sie bitte überprüfen, was falsch ist?
In App.razor:
Code: Select all
function WriteCookie(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.ToGmtString();
}
else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
}
function ReadCookie(name) {
const value = `; ${document.Cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length == 2) return parts.pop().split(';').shift();
}
Code: Select all
internal async Task PerformLogin()
{
Data.User.User? loggedInUser = await Data.User.Loader.ReadUsersForLogin(_username, _password);
if (loggedInUser != null)
{
AuthenticationState authenticationState = await ((CustomAuthStateProvider)AuthStateProvider).ChangeUser(loggedInUser.UserName, loggedInUser.Id, loggedInUser.Rank.ToString());
MudDialog?.Close(DialogResult.Ok(true));
}
}
Code: Select all
MainLayout.razorCode: Select all
private async void ShowLoginDialog(MouseEventArgs args)
{
var parameters = new DialogParameters { { "IsDarkMode", this._isDarkMode } };
MudBlazor.IDialogReference? dialog = await DialogService.ShowAsync("Login", parameters);
DialogResult? result = await dialog.Result;
if (result != null && !result.Canceled)
{
StateHasChanged();
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
_authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
_user = _authState.User;
if (_user.Identity != null && _user.Identity.IsAuthenticated)
{
var roleClaim = _user.FindFirst(System.Security.Claims.ClaimTypes.Role);
if (roleClaim != null)
{
_rank = (Data.User.User.Ranks)Enum.Parse(typeof(Data.User.User.Ranks), roleClaim.Value);
}
}
}
Code: Select all
CustomAuthStateProvider.csCode: Select all
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.IdentityModel.Tokens;
using Microsoft.JSInterop;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
public class CustomAuthStateProvider : AuthenticationStateProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IJSRuntime _js;
public CustomAuthStateProvider(IHttpContextAccessor httpContextAccessor, IJSRuntime js)
{
this._httpContextAccessor = httpContextAccessor;
this._js = js;
}
public override async Task GetAuthenticationStateAsync()
{
string usertoken = "";
if (_httpContextAccessor.HttpContext != null)
{
if (!_httpContextAccessor.HttpContext.Response.HasStarted)
{
usertoken = _httpContextAccessor.HttpContext.Request.Cookies["usertoken"];
}
else
{
usertoken = await _js.InvokeAsync("ReadCookie", "usertoken");
}
}
else
{
usertoken = await _js.InvokeAsync("ReadCookie", "usertoken");
}
if (string.IsNullOrEmpty(usertoken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
var tokenHandler = new JwtSecurityTokenHandler();
var identity = new ClaimsIdentity(tokenHandler.ReadJwtToken(usertoken).Claims, CookieAuthenticationDefaults.AuthenticationScheme);
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(identity)));
}
public async Task ChangeUser(string username, Guid guidId, string rank)
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Sid, guidId.ToString()),
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, rank)
}, CookieAuthenticationDefaults.AuthenticationScheme);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = identity,
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = null // No signing key
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
var usertoken = tokenHandler.WriteToken(token);
//when Anonymous set empty cookie
if (username == "Anonymous")
{
usertoken = "";
}
if (_httpContextAccessor.HttpContext != null)
{
if (!_httpContextAccessor.HttpContext.Response.HasStarted)
{
_httpContextAccessor.HttpContext.Response.Cookies.Append("usertoken", usertoken);
}
else
{
await _js.InvokeVoidAsync("WriteCookie", "usertoken", usertoken, DateTime.Now.AddMinutes(1));
}
}
else
{
await _js.InvokeVoidAsync("WriteCookie", "usertoken", usertoken, DateTime.Now.AddMinutes(1));
}
var authState = await this.GetAuthenticationStateAsync();
this.NotifyAuthenticationStateChanged(Task.FromResult(authState));
return authState;
}
public async Task Logout()
{
await ChangeUser("Anonymous", Guid.Empty, "Anonymous");
var authState = await this.GetAuthenticationStateAsync();
this.NotifyAuthenticationStateChanged(Task.FromResult(authState));
return authState;
}
}
Code: Select all
builder.Services.AddScoped();
builder.Services.AddHttpContextAccessor();
builder.Services.AddCascadingAuthenticationState();
Das JavaScript wird jetzt geladen, weil ich den Code in App.razor wie folgt geändert habe.
Code: Select all
function WriteCookie(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
}
function ReadCookie(name) {
console.log("test");
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Das Feld AuthenticationState? _authState ist null, wenn die Seite aktualisiert wird.
Mobile version