ASP.NET Core Jwt 认证
安装Microsoft.AspNetCore.Authentication.JwtBearer
Nuget包
appsettings.json中,添加JWT的配置,注意SecretKey
不能设置成太短的纯数字,不然要报错
"JWT": {
"Issuer": "AudienceUpgrade", //发行人
"Audience": "UpgradeService", //拥有者
"SecretKey": "900BA04D853C4DDF9CBF8B2B406EB4B6", //16位以上
"Expires": 7 //过期时间 单位:天
}
添加Jwt服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true, //是否验证Issuer
ValidIssuer = builder.Configuration["Jwt:Issuer"], //发行人Issuer
ValidateAudience = true, //是否验证Audience
ValidAudience = builder.Configuration["Jwt:Audience"], //订阅人Audience
ValidateIssuerSigningKey = true, //是否验证SecurityKey
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"])), //SecurityKey
ValidateLifetime = true, //是否验证失效时间
ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
RequireExpirationTime = true,
};
//自定义认证不过的返回值
options.Events = new JwtBearerEvents
{
OnChallenge = async context =>
{
context.HandleResponse();
context.Response.ContentType = "application/json;charset=utf-8";
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync("{\"message\":\"Unauthorized\",\"success\":false}");
}
};
});
启用认证
app.UseAuthentication();
app.UseAuthorization();
添加一个JWT帮助类
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Security.Claims;
using System.Text;
namespace WebApplication2
{
public class TokenHelper
{
private readonly IConfiguration _configuration;
public TokenHelper(IConfiguration configuration)
{
_configuration = configuration;
}
/// <summary>
/// 创建加密JwtToken
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public string CreateJwtToken<T>(T t)
{
// 定义用户信息
//var claims = new Claim[]
//{
// new Claim(ClaimTypes.Name, "123456"),
// new Claim(JwtRegisteredClaimNames.Email, "66666666666@qq.com"),
//};
var claimList = new List<Claim>();
foreach (var item in typeof(T).GetProperties()) claimList.Add(new Claim(item.Name, item.GetValue(t)!.ToString()!));
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretKey"]));
var expires = Convert.ToDouble(_configuration["JWT:Expires"]);
var algorithm = SecurityAlgorithms.HmacSha256;//选择加密算法
var signingCredentials = new SigningCredentials(secretKey, algorithm);
JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
_configuration["JWT:Issuer"], //Issuer
_configuration["JWT:Audience"], //Audience
claims: claimList,
DateTime.Now, //notBefore
DateTime.Now.AddDays(expires), //expires
signingCredentials //Credentials
);
string jwtToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return jwtToken;
}
/// <summary>
/// 通过Token获取对象信息,实体类字段必须全部是string类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Token"></param>
/// <returns></returns>
public T GetTokenObj<T>(string Token)
{
var jwt = Token.Replace("Bearer ", string.Empty).TrimStart();
Type t = typeof(T);
object obj = Activator.CreateInstance(t)!;
var jwtInfo = new JwtSecurityTokenHandler().ReadJwtToken(jwt);
foreach (var item in jwtInfo.Claims)
{
PropertyInfo _Property = t.GetProperty(item.Type);
if (_Property != null && _Property.CanRead)
_Property.SetValue(obj, item.Value, null);
}
return (T)obj;
}
/// <summary>
/// Token是否是符合要求的标准 Json Web 令牌
/// </summary>
/// <param name="tokenStr"></param>
/// <returns></returns>
public bool IsCanReadToken(ref string tokenStr)
{
if (string.IsNullOrWhiteSpace(tokenStr) || tokenStr.Length < 7)
return false;
if (!tokenStr.Substring(0, 6).Equals(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme))
return false;
tokenStr = tokenStr.Substring(7);
bool isCan = new JwtSecurityTokenHandler().CanReadToken(tokenStr);
return isCan;
}
}
}
注入生命周期
builder.Services.AddSingleton<TokenHelper>();
使用JWT
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace WebApplication2.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly TokenHelper _tokenHelper;
public WeatherForecastController(TokenHelper tokenHelper)
{
_tokenHelper = tokenHelper;
}
[Authorize]
[HttpGet("GetWeatherForecast")]
public string Get()
{
string tokenStr = Request.Headers["Authorization"].ToString();
//获取相关信息,实体类字段必须全部是string类型
var obj = _tokenHelper.GetTokenObj<Login>(tokenStr);
return JsonSerializer.Serialize(obj);
}
/// <summary>
/// 登录
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("Login")]
public string Login()
{
var t = new Login { Id=Guid.NewGuid().ToString() };
return _tokenHelper.CreateJwtToken(t);
}
}
public class Login
{
public string Id { get; set; }
}
}
控制器加上特性
//添加Jwt认证
[Authorize]
//取消认证
[AllowAnonymous]