.NET Framework 中对webapi进行jwt验证
最近在项目中对webapi进行了jwt验证,做一个记录
- 有关于jwt生成和验证token的操作全部记录在jwthelper.cs文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | /// <summary> /// 授权JWT类 /// </summary> public class JwtHelper { public readonly string SecretKey = System.Configuration.ConfigurationManager.AppSettings[ "SecretKey" ]; public readonly string AppId = System.Configuration.ConfigurationManager.AppSettings[ "AppId" ]; public readonly string AppKey = System.Configuration.ConfigurationManager.AppSettings[ "AppKey" ]; /// <summary> /// 创建Token 这里面可以保存自己想要的信息 /// </summary> /// <param name="user_id"></param> /// <param name="mobile"></param> /// <returns></returns> public string CreateToken( string user_id) { // 1. 定义需要使用到的Claims var claims = new Claim[] { new Claim( "user_id" , user_id), /* 可以保存自己想要信息,传参进来即可 new Claim("limit", "limit"), */ }; // 2. 从 appsettings.json 中读取SecretKey var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey)); // 3. 选择加密算法 var algorithm = SecurityAlgorithms.HmacSha256; // 4. 生成Credentials var signingCredentials = new SigningCredentials(secretKey, algorithm); // 5. 根据以上,生成token var jwtSecurityToken = new JwtSecurityToken( issuer: AppId, //Issuer audience: AppKey, //Audience claims: claims, //Claims, notBefore: DateTime.Now, //notBefore expires: DateTime.Now.AddHours(1), //expires signingCredentials: signingCredentials //Credentials ); // 6. 将token变为string var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); return token; } /// <summary> /// 根据token反向解析 /// </summary> /// <param name="token"></param> /// <returns></returns> public string GetInfoFromToken( string token = null ) { if (token is null || token == "" ) return null ; string tokenStr = token.Replace( "Bearer " , "" ); var handler = new JwtSecurityTokenHandler(); // string tokenStr = token; var payload = handler.ReadJwtToken(tokenStr).Payload; var claims = payload.Claims; var userid = claims.First(claim => claim.Type == "user_id" )?.Value; return userid; } /// <summary> /// 从Token中获取用户身份 /// </summary> /// <param name="token"></param> /// <param name="securityKey">securityKey明文,Java加密使用的是Base64</param> /// <returns></returns> public ClaimsPrincipal GetPrincipal( string token) { try { string securityKey = SecretKey; token = token.Replace( "Bearer " , "" ); var handler = new JwtSecurityTokenHandler(); TokenValidationParameters tokenValidationParameters = new TokenValidationParameters { ValidateAudience = false , ValidateIssuer = false , ValidateIssuerSigningKey = true , IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)), ValidateLifetime = false }; return handler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken); } catch (Exception ex) { return null ; } } /// <summary> /// 校验Token /// </summary> /// <param name="token">token</param> /// <returns></returns> public bool CheckToken( string token) { var principal = GetPrincipal(token); if (principal is null ) { return false ; } return true ; } |
2. 控制器中添加获取token的方法
/// <summary> /// 获取Token /// </summary> /// <returns></returns> [System.Web.Http.HttpGet] public async Task<string> GetToken(string userid) { //参数验证等等.... if (string.IsNullOrEmpty(userid)) { return await Task.FromResult("参数异常!"); } //这里可以连接数据库做账号密码验证 //这里可以做Redis缓存验证等等 //这里获取Token var token = await Task.Run(() => { return _jwt.CreateToken(userid); }); return token; }
根据该访问获取到token
2. 自定义SaveImgAttribute,继承ActionFilterAttribute过滤器并重写OnActionExecuting()方法
public class SaveImgAttribute : ActionFilterAttribute { public readonly string SecretKey = System.Configuration.ConfigurationManager.AppSettings["SecretKey"]; public readonly string AppId = System.Configuration.ConfigurationManager.AppSettings["AppId"]; public readonly string AppKey = System.Configuration.ConfigurationManager.AppSettings["AppKey"]; // 调用方法前 public override void OnActionExecuting(ActionExecutingContext actionContext) { Jwt.JwtHelper _jwt = new Jwt.JwtHelper(); var token = ""; if (actionContext.HttpContext.Request.Headers.AllKeys.Contains("Authorization")) { int index = actionContext.HttpContext.Request.Headers.AllKeys.Select((a, i) => i).Where(i => actionContext.HttpContext.Request.Headers.AllKeys[i] == "Authorization").FirstOrDefault(); token = actionContext.HttpContext.Request.Headers[index]; } if (token == null || token == "") { var Auth = new { Status = 401, Message = "身份验证失败" }; actionContext.Result = new ContentResult { ContentType = "application/json", Content = JsonConvert.SerializeObject(Auth) }; return; } bool isOK = _jwt.CheckToken(token); if (!isOK) { var Auth = new { Status = 401, Message = "身份验证失败" }; actionContext.Result = new ContentResult { ContentType = "application/json", Content = JsonConvert.SerializeObject(Auth) }; return; } var userid = _jwt.GetInfoFromToken(token); base.OnActionExecuting(actionContext); } }
3. 在控制器方法上加上[SaveImg]特性即可,每次调用对应方法的时候都会在SaveImgAttribute中进行 token验证
[SaveImg] [System.Web.Http.HttpPost] public async Task<JsonResult> SaveFileToOSS([FromBody] RequestBody request) {.....}
将GetToken()获取到的token添加到http请求头中(key:Authorization)(value:Bearer+空格+token)再进行对应方法的请求
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?