zoukankan      html  css  js  c++  java
  • 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里自己定义的,你改成别的状态码也是可以的,不过尽量还是要遵循国际惯例了

  • 相关阅读:
    RabbitMQ教程(二) ——linux下安装rabbitmq
    通讯协议序列化解读(二) protostuff详解教程
    头条号【编编成程】开通
    C++静态成员函数访问非静态成员的几种方法
    深入理解QStateMachine与QEventLoop事件循环的联系与区别
    『重构--改善既有代码的设计』读书笔记---Duplicate Observed Data
    GCC选项-Xlinker和-Wl区别
    『重构--改善既有代码的设计』读书笔记----Replace Array with Object
    解决GDB输出Qt内置类型的显示问题
    GDB源代码查找路径
  • 原文地址:https://www.cnblogs.com/bjjjunjie/p/12361023.html
Copyright © 2011-2022 走看看