.NET Framework 中对webapi进行jwt验证
最近在项目中对webapi进行了jwt验证,做一个记录
- 有关于jwt生成和验证token的操作全部记录在jwthelper.cs文件中:
/// <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)再进行对应方法的请求


浙公网安备 33010602011771号