步骤1:使用Blazor WASM创建一个新项目。 步骤2:安装Microsoft.AspNetCore.Components.Authorization软件包。 步骤3:创建自定义身份验证状态以存储JWT令牌和用户信息。
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
public CustomAuthenticationStateProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
public override async Task GetAuthenticationStateAsync()
{
var token = await GetTokenAsync();
var identity = string.IsNullOrEmpty(token)
? new ClaimsIdentity()
: new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt");
return new AuthenticationState(new ClaimsPrincipal(identity));
}
public async Task GetTokenAsync()
{
return await _httpClient.GetStringAsync("api/getToken");
}
private IEnumerable ParseClaimsFromJwt(string jwt)
{
var payload = jwt.Split('.')[1];
var jsonBytes = JwtBase64Url.Decode(payload);
var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
var claims = keyValuePairs
.SelectMany(x => ExtractClaimsFromDictionary(x.Key, x.Value));
return claims;
}
private IEnumerable ExtractClaimsFromDictionary(string key, object value)
{
if (value is not JsonElement element)
{
yield return new Claim(key, value.ToString());
yield break;
}
if (element.ValueKind == JsonValueKind.Number && element.TryGetInt32(out var intVal))
{
yield return new Claim(key, intVal.ToString());
yield break;
}
if (element.ValueKind == JsonValueKind.Boolean)
{
yield return new Claim(key, element.GetBoolean().ToString());
yield break;
}
if (element.ValueKind == JsonValueKind.String)
{
if (DateTimeOffset.TryParse(element.GetString(), out var dateTimeOffset))
{
yield return new Claim(key, dateTimeOffset.ToString("o", CultureInfo.InvariantCulture));
yield break;
}
yield return new Claim(key, element.GetString());
yield break;
}
if (element.ValueKind == JsonValueKind.Array)
{
var jArray = (JsonElement.ArrayEnumerator)element.EnumerateArray();
var arrayIndex = 0;
while (jArray.MoveNext())
{
var arrayValue = jArray.Current;
var nestedKey = $"{key}:{arrayIndex++}";
foreach (var nestedClaim in ExtractClaimsFromDictionary(nestedKey, arrayValue))
{
yield return nestedClaim;
}
}
yield break;
}
if (element.ValueKind == JsonValueKind.Object)