Проблема с сохранением претензии в Blazor Server

У меня проблема с хранением утверждений, когда я использую @context.User.Identity.Name для получения значения, но его не удается найти. Я пробовал каждый метод, но он остается прежним. Я не знаю, где я ошибся. Этот код создает токен Jwt в методе класса AuthenticationStaffOnly с именем GenerateJwtToken. После этого он будет отправлен в Login.razor для хранения в LocalStorage. Затем вызывается GetAuthenticationStateAsync, чтобы проверить, действителен ли токен Jwt, а затем сохранить его в утверждении и перейти на другие страницы с атрибутом [Authorize(Roles = "Admin,Staff")].

Index.razor для выходных требований

<AuthorizeView>
    <Authorized>
        <h1>Hello, @context.User.Identity?.Name </h1>
    </Authorized>
    <NotAuthorized>
        @context.User.Identity.Name
        @string.Join(",", ((ClaimsIdentity)context.User.Identity).Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value))
        <p>Your email is: @context.User.FindFirstValue("email")</p>
        <h1>คุณยังไม่ได้เข้าสู่ระบบ หรือ ไม่มีสิทธิเข้าถึงหน้านี้</h1>
    </NotAuthorized>
</AuthorizeView>

AuthenticationStaffOnly.cs

using ComEsport.Models;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Linq;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace ComEsport.Services
{
    public class AuthenticationStaffOnly : AuthenticationStateProvider
    {
        private readonly ILogger<StaffService> _logger;
        private readonly IConfiguration _configuration;
        private readonly ILocalStorageService _localStorage;
        private readonly HttpClient _http;
        private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
        private readonly IHttpContextAccessor _httpContextAccessor;
        public AuthenticationStaffOnly(ILogger<StaffService> logger, IConfiguration configuration, ILocalStorageService localStorage, HttpClient http, JwtSecurityTokenHandler jwtSecurityTokenHandler, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _configuration = configuration;
            _localStorage = localStorage;
            _http = http;
            _jwtSecurityTokenHandler = jwtSecurityTokenHandler;
            _httpContextAccessor = httpContextAccessor;
        }
        /// <summary>
        /// สำหรับการสร้าง JwtToken และลงทะเบียน
        /// </summary>
        /// <param name = "staff"></param>
        /// <returns></returns>
        public async Task<string?> GenerateJwtToken(Staff staff)
        {
            if (staff.StaffEmail == null) return null;
            byte[] Key = Convert.FromBase64String(_configuration["JWTSettings:SecretKey"]);
            SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Key);

            SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                new Claim(ClaimTypes.Email, staff.StaffEmail),
                new Claim(ClaimTypes.Name, staff.StaffFirstName + staff.StaffLastName),
                new Claim(ClaimTypes.Role, staff.StaffPermission)
            }),
                Expires = DateTime.UtcNow.AddMinutes(25),
                SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature)
            };
            JwtSecurityToken token = _jwtSecurityTokenHandler.CreateJwtSecurityToken(descriptor);
            _logger.LogInformation("Generate Jwt Token Success from AuthenticationStaffOnly Method GenerateJwtToken");
            return _jwtSecurityTokenHandler.WriteToken(token);
        }
        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            // ดึง Jwt Token ออกจาก localStorage
            string jsonString = await _localStorage.GetItemAsStringAsync("access_token");
            // แปลง access_token โดยปกติจะมี Model TokenClass ติดมาด้วยจำเป็นต้องแปลงออก เพื่อจะนำไปอ่าน jwt Token 
            JObject json = JObject.Parse(jsonString);
            string token = json.GetValue("TokenOrMessage").Value<string>();
            var TokenData = _jwtSecurityTokenHandler.ReadJwtToken(token);

            // สร้าง identity และ claimsPrincipal จาก Jwt Token
            var claims = new List<Claim>();
            claims.AddRange(TokenData.Claims.Select(claim => new Claim(claim.Type, claim.Value)));
            var identity = new ClaimsIdentity(claims, "Jwt");
            var claimsPrincipal = new ClaimsPrincipal(identity);
            var state = new AuthenticationState(claimsPrincipal);
            NotifyAuthenticationStateChanged(Task.FromResult(state));

            return state;
        }
    }
}

Значение @Context равно null и NotAuthorized.

Отладка формы результатов

Значение переменной из оператора 'var TokenData = _jwtSecurityTokenHandler.ReadJwtToken(token);' такой же, как и раньше.

переменные требования

идентификатор переменной

переменные требованияОсновной

переменное состояние

Не удалось передать, не могли бы вы загрузить минимальный пример, который можно было бы репо? Я получаю NotAuthorized только тогда, когда не регистрировал AuthenticationStaffOnly. Но в этом случае при отладке я не попаду в метод GetAuthenticationStateAsync()

Ruikai Feng 18.04.2023 04:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я могу сделать это, добавив эту строку кода:

_httpContext.User.AddIdentity(identity);

Другие вопросы по теме