I have a problem with storing Claims when I use @context.User.Identity.Name to retrieve the value but it cannot be found. I have tried every method but it remains the same. I don't know where I went wrong. This code generates a Jwt Token in the AuthenticationStaffOnly class method named GenerateJwtToken. After that, it will be sent to Login.razor to store in LocalStorage. Then, GetAuthenticationStateAsync is called to check whether the Jwt Token is valid or not, and then save it in the Claim and go to other pages with the [Authorize(Roles = "Admin,Staff")] attribute.
Index.razor For Output Claims
<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;
}
}
}
The @Context value is null and NotAuthorized