隐藏

.Net6 实现 JWT

发布:2022/7/13 22:49:42作者:管理员 来源:本站 浏览次数:1079

.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;

       }

   }

}