webapi使用jwt做权限验证

Posted 晨冬之雪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webapi使用jwt做权限验证相关的知识,希望对你有一定的参考价值。

 考虑到很多公司目前并没有切换到.netcore,所有本文尝试使用.netframework下的webapi

 

首先使用Nuget 安装 jwt包

安装完成后,创建 jwt的帮助类

public  class JwtToken
    {
        static IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//HMACSHA256加密
        static IJsonSerializer serializer = new JsonNetSerializer();//序列化和反序列
        static IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//Base64编解码
        static IDateTimeProvider provider = new UtcDateTimeProvider();//UTC时间获取
        const string secret = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4aKpVo2OHXPwb1R7duLgg";//服务端
        /// <summary>
        /// 创建token
        /// </summary>
        /// <param name="payload">字典对象</param>
        /// <returns></returns>
        public static string CreateJWT(Dictionary<string, object> payload)
        {
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            return encoder.Encode(payload, secret);
        }
        /// <summary>
        /// 验证token
        /// </summary>
        /// <param name="token">token值</param>
        /// <param name="payload">token还原后的字典</param>
        /// <param name="message">验证结果</param>
        /// <returns></returns>
        public static bool ValidateJWT(string token, out string payload, out string message)
        {
            bool isValidted = false;
            payload = "";
            try
            {
                IJwtValidator validator = new JwtValidator(serializer, provider);//用于验证JWT的类
              //  IJwtAlgorithm algorithm= new HMACSHA256Algorithm();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder,algorithm);//用于解析JWT的类
                payload = decoder.Decode(token, secret, verify: true);

                isValidted = true;

                message = "验证成功";
            }
            catch (TokenExpiredException)//当前时间大于负载过期时间(负荷中的exp),会引发Token过期异常
            {
                message = "过期了!";
            }
            catch (SignatureVerificationException)//如果签名不匹配,引发签名验证异常
            {
                message = "签名错误!";
            }
            return isValidted;
        }
    }

然后创建相关的Model

 public class LoginResult
    {
        public bool Success { get; set; }

        public string Token { get; set; }

        public string Message { get; set; }
    }

创建获取token的api

        public LoginResult Post([FromBody]LoginRequest request)
        {

            LoginResult rs = new LoginResult();
            //这是是获取用户名和密码的,这里只是为了模拟
            if (request.UserName == "admin" && request.Password == "123456")
            {

           
                try
                {
                    var payload = new Dictionary<string, object>
            {
                { "username","admin"},//发行人
                { "exp", DateTimeOffset.UtcNow.AddSeconds(100).ToUnixTimeSeconds() },//到期时间
     
            };
                    rs.Token = JwtToken.CreateJWT(payload);
                    rs.Success = true;
                }
                catch (Exception ex)
                {
                    rs.Message = ex.Message;
                    rs.Success = false;
                }
            }
            else
            {
                rs.Message = "fail";
                rs.Success = false;
            }
            return rs;
        }

创建验证token的filter

 public class ApiAuthorizeAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
            bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute);
            if (!isAnonymous)
            {
               var rq= actionContext.Request.Properties;
               
                var authorization = actionContext.Request.Headers.Authorization;
                 if (authorization==null)
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }
                else
                {
                    string ResultMessage;//需要解析的消息
                    string Payload;//获取负载
                    var result = JwtToken.ValidateJWT(authorization.Scheme, out Payload, out ResultMessage); //TokenManager.ValidateToken(authorization.Scheme);
                    if (!result)
                    {
                        actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                    }
                }
             
            }
        }

最后把特性加到需要需要验证的Action上

     // GET: User
        [ApiAuthorize]
        public string Get()
        {
      
                return $"获取到了";
           
        }

然后进行测试,首先获取token

 

 调用接口,并传入token值

 

 如果不传入token值,那么会报401错误

 

 当然了,那个401错误其实是在filter里自己定义的,你改成别的状态码也是可以的,不过尽量还是要遵循国际惯例了

 

以上是关于webapi使用jwt做权限验证的主要内容,如果未能解决你的问题,请参考以下文章

如何在.net6webapi中配置Jwt实现鉴权验证

springboot项目集成jwt做权限验证,详细步骤

用户权限更改后 JWT 刷新

beego应用做纯API后端如何使用jwt实现无状态权限验证

使用 Microsoft System.IdentityModel.Tokens.Jwt 在 Asp.net WebApi 中实现 JWT 身份验证

使用 JWT 令牌的 ASP.NET Core 网站到 WebApi 身份验证