.Net Core中进行Jwt验证

授权JWT类JwtHelper.cs

  1     /// <summary>
  2     /// 授权JWT类
  3     /// </summary>
  4     public class JwtHelper
  5     {
  6         private readonly IConfiguration _configuration;
  7 
  8         /// <summary>
  9         /// Token配置
 10         /// </summary>
 11         /// <param name="configuration"></param>
 12         public JwtHelper(IConfiguration configuration)
 13         {
 14             _configuration = configuration;
 15         }
 16 
 17         /// <summary>
 18         /// 创建Token 这里面可以保存自己想要的信息
 19         /// </summary>
 20         /// <param name="user_id"></param>
 21         /// <param name="mobile"></param>
 22         /// <returns></returns>
 23         public string CreateToken(string user_id)
 24         {
 25             // 1. 定义需要使用到的Claims
 26             var claims = new Claim[]
 27             {
 28                 new Claim("user_id", user_id),            
 29                 /* 可以保存自己想要信息,传参进来即可           
 30                 new Claim("limit", "limit"),            
 31                 */
 32             };
 33 
 34             // 2. 从 appsettings.json 中读取SecretKey
 35             var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
 36 
 37             // 3. 选择加密算法
 38             var algorithm = SecurityAlgorithms.HmacSha256;
 39 
 40             // 4. 生成Credentials
 41             var signingCredentials = new SigningCredentials(secretKey, algorithm);
 42 
 43             // 5. 根据以上,生成token
 44             var jwtSecurityToken = new JwtSecurityToken(
 45                issuer: _configuration["Jwt:AppId"],    //Issuer
 46                audience: _configuration["Jwt:AppKey"],  //Audience
 47                claims: claims,                          //Claims,
 48                notBefore: DateTime.Now,                    //notBefore
 49                expires: DateTime.Now.AddHours(1),     //expires
 50                signingCredentials: signingCredentials               //Credentials
 51             );
 52 
 53             // 6. 将token变为string
 54             var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
 55 
 56             return token;
 57         }
 58 
 59         /// <summary>
 60         /// 根据token反向解析
 61         /// </summary>
 62         /// <param name="token"></param>
 63         /// <returns></returns>
 64         public string GetInfoFromToken(string token = null)
 65         {
 66             if (token is null || token == "")
 67                 return null;
 68 
 69             string tokenStr = token.Replace("Bearer ", "");
 70 
 71             var handler = new JwtSecurityTokenHandler();
 72             // string tokenStr = token;
 73             var payload = handler.ReadJwtToken(tokenStr).Payload;
 74 
 75             var claims = payload.Claims;
 76 
 77             var info = new
 78             {
 79                 UserId = claims.First(claim => claim.Type == "user_id")?.Value,
 80                 AppId = _configuration["Jwt:AppId"],
 81                 AppKey = _configuration["Jwt:AppKey"]
 82             };
 83             return JsonConvert.SerializeObject(info);
 84         }
 85 
 86         /// <summary>
 87         /// 从Token中获取用户身份
 88         /// </summary>
 89         /// <param name="token"></param>
 90         /// <param name="securityKey">securityKey明文,Java加密使用的是Base64</param>
 91         /// <returns></returns>
 92         public ClaimsPrincipal GetPrincipal(string token)
 93         {
 94             try
 95             {
 96                 string securityKey = _configuration["Jwt:SecretKey"];
 97                 token = token.Replace("Bearer ", "");
 98                 var handler = new JwtSecurityTokenHandler();
 99                 TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
100                 {
101                     ValidateAudience = false,
102                     ValidateIssuer = false,
103                     ValidateIssuerSigningKey = true,
104                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)),
105                     ValidateLifetime = false
106                 };
107                 return handler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
108             }
109             catch (Exception ex)
110             {
111 
112                 return null;
113             }
114         }
115 
116 
117         /// <summary>
118         /// 校验Token
119         /// </summary>
120         /// <param name="token">token</param>
121         /// <returns></returns>
122         public bool CheckToken(string token)
123         {
124             var principal = GetPrincipal(token);
125             if (principal is null)
126             {
127                 return false;
128             }
129             return true;
130         }
131     }

在控制器中添加对应校验

 1     [Route("api/[controller]/[action]")]
 2     [ApiController]
 3     public class UserInfoController : ControllerBase
 4     {
 5         private readonly JwtHelper _jwt;
 6 
 7         /// <summary>
 8         /// 初始化
 9         /// </summary>
10         /// <param name="jwtHelper"></param>
11         public UserInfoController(JwtHelper jwtHelper)
12         {
13             _jwt = jwtHelper;
14         }
15         /// <summary>
16         /// 获取Token
17         /// </summary>
18         /// <returns></returns>
19         [HttpPost]
20         public IActionResult GetToken(string userid)
21         {
22             //参数验证等等....
23             if (string.IsNullOrEmpty(userid))
24             {
25                 return Ok("参数异常!");
26             }
27             //这里可以连接mysql数据库做账号密码验证
28 
29             //这里可以做Redis缓存验证等等
30             //这里获取Token,当然,这里也可以选择传结构体过去
31             var token = _jwt.CreateToken(userid);
32             return Ok(token);
33         }
34 
35         /// <summary>
36         /// 获取自己的详细信息,其中 [Authorize] 就表示要带Token才行
37         /// </summary>
38         /// <returns></returns>
39         [HttpPost]
40         [Authorize]
41         public IActionResult GetSelfInfo()
42         {
43             //执行到这里,就表示已经验证授权通过了
44             /*
45              * 这里返回个人信息有两种方式
46              * 第一种:从Header中的Token信息反向解析出用户账号,再从数据库中查找返回
47              * 第二种:从Header中的Token信息反向解析出用户账号信息直接返回,当然,在前面创建        Token时,要保存进使用到的Claims中。
48             */
49             var token = Request.Headers.Authorization.ToString();
50             bool isOK = _jwt.CheckToken(token);
51 
52             var data = _jwt.GetInfoFromToken(token);
53             return Ok("授权通过了!");
54 
55         }
56     }

 Program.cs中进行配置

 1     public class Program
 2     {
 3         public static void Main(string[] args)
 4         {
 5             var builder = WebApplication.CreateBuilder(args);
 6 
 7             // Add services to the container.
 8 
 9             builder.Services.AddControllers();
10             // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
11             builder.Services.AddEndpointsApiExplorer();
12             builder.Services.AddSwaggerGen();
13             #region JWT服务
14             // 注册JWT服务
15             builder.Services.AddSingleton(new JwtHelper(builder.Configuration));
16 
17             builder.Services.AddAuthentication(options =>
18             {
19                 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
20             }
21             ).AddJwtBearer(options =>
22             {
23                 options.TokenValidationParameters = new TokenValidationParameters()
24                 {
25                     ValidateIssuer = true, //是否验证Issuer
26                     ValidIssuer = builder.Configuration["Jwt:AppId"], //发行人Issuer
27                     ValidateAudience = true, //是否验证Audience
28                     ValidAudience = builder.Configuration["Jwt:AppKey"], //订阅人Audience
29                     ValidateIssuerSigningKey = true, //是否验证SecurityKey
30                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"])), //SecurityKey
31                     ValidateLifetime = true, //是否验证失效时间
32                     ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
33                     RequireExpirationTime = true,
34                 };
35             }
36             );
37             #endregion
38             var app = builder.Build();
39 
40             // Configure the HTTP request pipeline.
41             if (app.Environment.IsDevelopment())
42             {
43                 app.UseSwagger();
44                 app.UseSwaggerUI();
45             }
46 
47             app.UseHttpsRedirection();
48 
49             app.UseAuthentication();
50             app.UseAuthorization();
51 
52 
53             app.MapControllers();
54 
55             app.Run();
56         }
57     }

appsettings.json中配置

 1 {
 2   "Logging": {
 3     "LogLevel": {
 4       "Default": "Information",
 5       "Microsoft.AspNetCore": "Warning"
 6     }
 7   },
 8   "AllowedHosts": "*",
 9   "Jwt": {
10     "SecretKey": "u6u^Bdob@OJ&KF2RcAB%ybsoy&2S7jhP^SW!q!Z^FK7eB7F8CcxIHsIh4Ll3pL^#",
11     "AppId": "WebAppAppId",
12     "AppKey": "WebAppAudience"
13   }
14 }

 

posted @ 2023-05-15 14:45  没有童话的鱼  阅读(153)  评论(0编辑  收藏  举报