Microsoft.AspNetCore.Authentication.JwtBearer
2、API增加认证[Authorize]给Controller一个方法增加认证访问。
3、添加认证服务builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidIssuer = builder.Configuration["JwtIssuer"],//Configuration配置文件中获取
ValidAudience = builder.Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtSecurityKey"]))
};
});
二、WebApi配置JWT授权
这里我们把授权写在登录中
var claims = new[]{ new Claim(ClaimTypes.Name, user.Name) }; //这里存储用户名
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiry = DateTime.Now.AddSeconds(Convert.ToInt32(_configuration["JwtExpiryMinute"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtAudience"],
claims,
expires: expiry,
signingCredentials: creds
);
var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
三、Blazor前端配置
1、NuGet安装引用
Blazored.LocalStorage
Microsoft.AspNetCore.Components.Authorization
2、配置服务builder.Services.AddBlazoredLocalStorage(); builder.Services.AddAuthorizationCore(); builder.Services.AddScoped();3、验证脚本
public class ApiAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
private readonly ILocalStorageService _localStorage;
private const string tokenKey = "authToken";
public ApiAuthenticationStateProvider(HttpClient httpClient, ILocalStorageService localStorage)
{
_httpClient = httpClient;
_localStorage = localStorage;
}
public override async Task GetAuthenticationStateAsync()
{
var savedToken = await _localStorage.GetItemAsync(tokenKey);
IEnumerable claims = null;
if (string.IsNullOrWhiteSpace(savedToken))
{
MarkUserAsLoggedOut();
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
else
{
claims = ParseClaimsFromJwt(savedToken);
}
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt")));
}
public async Task MarkUserAsAuthenticated(string token)
{
await _localStorage.SetItemAsync(tokenKey, token);
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"));
var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
NotifyAuthenticationStateChanged(authState);
}
public void MarkUserAsLoggedOut()
{
var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
var authState = Task.FromResult(new AuthenticationState(anonymousUser));
NotifyAuthenticationStateChanged(authState);
}
private IEnumerable ParseClaimsFromJwt(string jwt)
{
var claims = new List();
var payload = jwt.Split('.')[1];
var jsonBytes = ParseBase64WithoutPadding(payload);
var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
if (roles != null)
{
if (roles.ToString().Trim().StartsWith("["))
{
var parsedRoles = JsonSerializer.Deserialize(roles.ToString());
foreach (var parsedRole in parsedRoles)
{
claims.Add(new Claim(ClaimTypes.Role, parsedRole));
}
}
else
{
claims.Add(new Claim(ClaimTypes.Role, roles.ToString()));
}
keyValuePairs.Remove(ClaimTypes.Role);
}
claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
return claims;
}
private byte[] ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
}public class ApiAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
private readonly ILocalStorageService _localStorage;
private const string tokenKey = "authToken";
public ApiAuthenticationStateProvider(HttpClient httpClient, ILocalStorageService localStorage)
{
_httpClient = httpClient;
_localStorage = localStorage;
}
public override async Task GetAuthenticationStateAsync()
{
var savedToken = await _localStorage.GetItemAsync(tokenKey);
IEnumerable claims = null;
if (string.IsNullOrWhiteSpace(savedToken))
{
MarkUserAsLoggedOut();
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
else
{
claims = ParseClaimsFromJwt(savedToken);
}
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt")));
}
public async Task MarkUserAsAuthenticated(string token)
{
await _localStorage.SetItemAsync(tokenKey, token);
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"));
var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
NotifyAuthenticationStateChanged(authState);
}
public void MarkUserAsLoggedOut()
{
var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
var authState = Task.FromResult(new AuthenticationState(anonymousUser));
NotifyAuthenticationStateChanged(authState);
}
private IEnumerable ParseClaimsFromJwt(string jwt)
{
var claims = new List();
var payload = jwt.Split('.')[1];
var jsonBytes = ParseBase64WithoutPadding(payload);
var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
if (roles != null)
{
if (roles.ToString().Trim().StartsWith("["))
{
var parsedRoles = JsonSerializer.Deserialize(roles.ToString());
foreach (var parsedRole in parsedRoles)
{
claims.Add(new Claim(ClaimTypes.Role, parsedRole));
}
}
else
{
claims.Add(new Claim(ClaimTypes.Role, roles.ToString()));
}
keyValuePairs.Remove(ClaimTypes.Role);
}
claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
return claims;
}
private byte[] ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
}
4、配置验证过滤view
修改在App.razor中修改RouteView为AuthorizeRouteView,认证没通过跳转到登录界面
@Body
@Body
示例下载地址


