CustomAuthStateProvider в .NET 9, MudBlazorC#

Место общения программистов C#
Ответить
Anonymous
 CustomAuthStateProvider в .NET 9, MudBlazor

Сообщение Anonymous »

Я пытаюсь реализовать CustomAuthStateProvider. Цель состоит в том, чтобы соответствующий пользователь вошел в систему во всем приложении, а я мог получить имя, идентификатор (Guid) и ранг от поставщика на всех страницах.
Невозможно избежать перезагрузки страницы. Это также должно быть обеспечено, следовательно, и файл cookie.
Я уже спрашивал здесь о CustomAuthStateProvider, но, к сожалению, JavaScript не хочет загружаться в текущем приложении. Он находится в App.razor. Можете ли вы проверить, что не так?
В App.razor:

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();
}


В LoginDialog.razor:
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));
}
}

MainLayout.razor:
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);
}
}
}

CustomAuthStateProvider.cs:
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 id, string role)
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Sid, id.ToString()),
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, role)
}, 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;
}
}

В Program.cs:
builder.Services.AddScoped();
builder.Services.AddHttpContextAccessor();
builder.Services.AddCascadingAuthenticationState();


Подробнее здесь: https://stackoverflow.com/questions/798 ... -mudblazor
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»