.Net6 实现 JWT
(需了解知识)依赖注入
首先安装 Nuget 包 Microsoft.AspNetCore.Authentication.JwtBearer
Program.cs 里添加Jwt
//添加jwt验证:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = builder.Configuration["JWT:Issuer"],
ValidateAudience = true,
ValidAudience = builder.Configuration["JWT:Audience"],
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWT:SecretKey"]))
};
});
//下面的app添加这个 和这个长得很像 app.UseAuthorization();
app.UseAuthentication();//在前
app.UseAuthorization();//在后
在IOC容器里注入 JWT header类和我自己写的 TokenHelper类
//用于Jwt的各种操作
builder.RegisterType<JwtSecurityTokenHandler>().InstancePerLifetimeScope();
//自己写的支持泛型存入Jwt 便于扩展
builder.RegisterType<TokenHelper>().InstancePerLifetimeScope();
我的TokenHelper类 模型也放在这里 比如我放了一个实体进去拿token的时候也会拿出一个实体
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Security.Claims;
using System.Text;
namespace Quartz_Crawler.Tools
{
public class TokenHelper
{
private readonly IConfiguration _configuration;
private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
public TokenHelper(IConfiguration configuration, JwtSecurityTokenHandler jwtSecurityTokenHandler)
{
_configuration = configuration;
_jwtSecurityTokenHandler = jwtSecurityTokenHandler;
}
/// <summary>
/// 创建加密JwtToken
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public string CreateJwtToken<T>(T user)
{
var claimList = this.CreateClaimList(user);
// 从 appsettings.json 中读取SecretKey
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretKey"]));
// 从 appsettings.json 中读取Expires
var expires = Convert.ToDouble(_configuration["JWT:Expires"]);
// 选择加密算法
var algorithm = SecurityAlgorithms.HmacSha256;
// 生成Credentials
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 = _jwtSecurityTokenHandler.WriteToken(jwtSecurityToken);
return jwtToken;
}
public T GetToken<T>(string Token)
{
Type t = typeof(T);
object objA = Activator.CreateInstance(t);
var b = _jwtSecurityTokenHandler.ReadJwtToken(Token);
foreach (var item in b.Claims)
{
PropertyInfo _Property = t.GetProperty(item.Type);
if (_Property != null && _Property.CanRead)
{
_Property.SetValue(objA, item.Value, null);
}
}
return (T)objA;
}
/// <summary>
/// 创建包含用户信息的CalimList
/// </summary>
/// <param name="authUser"></param>
/// <returns></returns>
private List<Claim> CreateClaimList<T>(T authUser)
{
var Class = typeof(User);
List<Claim> claimList = new List<Claim>();
foreach (var item in Class.GetProperties())
{
claimList.Add(new Claim(item.Name, Convert.ToString(item.GetValue(authUser))));
}
return claimList;
}
}
/// <summary>
/// 登录用户信息
/// </summary>
public class User
{
public int UserID { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Role { get; set; }
public User(int userID=default, string name=default, string email=default, string role=default)
{
this.UserID = userID;
this.Name = name;
this.Email = email;
this.Role = role;
}
}
public class UserModel
{
public string UserID { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Role { get; set; }
public UserModel()
{
}
}
}
我这里是重新自定义了 认证标签 继承这个接口IAuthorizationFilter来实现
从header中获取 Authorization 来验证是否具有权限 以及用户信息 把用户信息存到类里 注入到容器就可以随时随地的拿到用户信息,而无需再从数据库里拿到信息
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Quartz_Crawler.Service;
using Quartz_Crawler.Tools;
using System.IdentityModel.Tokens.Jwt;
namespace Quartz_Crawler.Filter
{
public class LoginAttrbuteFilter : IAuthorizationFilter
{
private readonly IServiceFactory _serviceFactory;
public JwtSecurityTokenHandler _jwtSecurityTokenHandler;
private readonly TokenHelper _tokenHelper;
public LoginAttrbuteFilter(IServiceFactory serviceFactory, JwtSecurityTokenHandler jwtSecurityTokenHandler, TokenHelper tokenHelper)
{
_serviceFactory = serviceFactory;
_jwtSecurityTokenHandler = jwtSecurityTokenHandler;
_tokenHelper = tokenHelper;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var heads = context.HttpContext.Request.Headers["Authorization"];
var a= _tokenHelper.GetToken<UserModel>(header);
_serviceFactory.Get();
throw new NotImplementedException();
}
}
}
最后是我的 Controller 里面的代码
using Microsoft.AspNetCore.Mvc;
using Quartz_Crawler.Filter;
using Quartz_Crawler.Tools;
using System.IdentityModel.Tokens.Jwt;
namespace Quartz_Crawler.Controller
{
[ApiController]
public class HomeController : ControllerBase
{
private readonly ILogger<HomeController> _logger;
private readonly IConfiguration _configuration;
private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
private readonly TokenHelper _tokenHelper;
public HomeController(ILogger<HomeController> logger, IConfiguration configuration, JwtSecurityTokenHandler jwtSecurityTokenHandler, TokenHelper tokenHelper)
{
_logger = logger;
_configuration = configuration;
_jwtSecurityTokenHandler = jwtSecurityTokenHandler;
_tokenHelper = tokenHelper;
}
[HttpGet]
[Route("Login")]
public object Login()
{
var aaa = _tokenHelper.CreateJwtToken(new Tools.User(1, "22", "33", "44"));
return aaa;
}
[HttpGet]
[Route("Get")]
public object Get()
{
return null;
}
[HttpGet]
[Route("Post")]
[TypeFilter(typeof(LoginAttrbuteFilter))]
public object post()
{
return null;
}
}
}