.NET Framework 中对webapi进行jwt验证

最近在项目中对webapi进行了jwt验证,做一个记录

  1. 有关于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)再进行对应方法的请求

 

posted @ 2023-02-28 11:22  没有童话的鱼  阅读(176)  评论(0编辑  收藏  举报