net WebApi集成JWT实现对接口的鉴权

1.Nuget搜索JWT,安装最新版即可

在这里插入图片描述

1.自定义鉴权所需的对象(贴上我定义的对象,可根据自己的需求进行更改)

    /// <summary>
    /// JWT 签名认证对象、用于签发与校验Token
    /// </summary>
    public class Signature
    {
        /// <summary>
        /// 签发人名称
        /// </summary>
        public const string issName = "Rain.Wang";
        /// <summary>
        /// 构造器
        /// </summary>
        /// <param name="roles"></param>
        /// <param name="iss"></param>
        /// <param name="aud"></param>
        /// <param name="effectiveTime">签名有效时间,分钟</param>
        public Signature(string[] roleIn,string audIn, int effectiveTime) {
            this.role = roleIn;
            this.iss = issName;
            this.aud = audIn;
            //DateTime 转时间戳自行百度
            long time = SystemUtils.timeToTimeSpan(DateTime.Now) ;
            this.iat = time;
            this.exp = time + effectiveTime * 60 * 1000;
        }

        /// <summary>
        /// 用户权限集合
        /// </summary>
        public string[] role { get; set; }

        /// <summary>
        /// jwt的过期时间,时间戳形式
        /// </summary>
        public long exp { get; set; }

        /// <summary>
        /// jwt的签发时间
        /// </summary>
        public long iat { get; set; }

        /// <summary>
        /// jwt的签发人
        /// </summary>
        public string iss { get; set; }

        /// <summary>
        /// jwt的接收人用户名
        /// </summary>
        public string aud { get; set; }


    }

2.JWTUtils(自己封装的JWT工具类)

原始网页参考:https://github.com/jwt-dotnet/jwt

 
    public static class JWTUtils
    {
        /// <summary>
        /// JWT私钥
        /// </summary>
        private  const string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";

        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="signature"></param>
        /// <returns></returns>
        public static string  creatToken(Signature signature) {
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            var token = encoder.Encode(signature, secret);
            //Console.WriteLine(token);
            return token;
        }

        /// <summary>
        /// 解密Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>

        public static String  tokenToSignatureJson(String token) {
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);

                var json = decoder.Decode(token, secret, verify: true);
                Console.WriteLine(json);
                return json;
            }
            catch (TokenExpiredException)
            {
                Console.WriteLine("Token has expired;"+ "令牌已过期");
                return "fail";
            }
            catch (SignatureVerificationException)
            {
                Console.WriteLine("Token has invalid signature;"+ "令牌的签名无效");
                return "fail";
            }

        }
    }

3.RequestAuthorizeAttribute(接口请求过滤器)

    public class RequestAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 权限数组
        /// </summary>
        public string[] roles { get; set; }

        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
          
            //从http请求的头里面获取身份验证信息,验证是否是请求发起方的token
            var authorization = actionContext.Request.Headers.Authorization;

            //此接口不需要权限、所有人均可访问
            if (roles == null || roles.Length < 1)
            {
                base.IsAuthorized(actionContext);
            }
            //签名认证信息存在
            else if ((authorization != null) && (authorization.Parameter != null))
            {
                //校验Token是否合法
                if (Authentication(authorization.Parameter))
                {
                    base.IsAuthorized(actionContext);
                }
                else
                {
                    //授权失败
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            //接口需要权限认证,但无Token,返回拒绝响应此请求
            else {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                else HandleUnauthorizedRequest(actionContext);
            }

        }


        public bool Authentication(String token) {
            try
            {
                //Token校验结果
                string tokenDecrypt = JWTUtils.tokenToSignatureJson(token);
                //token校验失败
                if (tokenDecrypt == "fail")
                {
                    return false;
                }

                else
                {

                    Signature signature = JsonConvert.DeserializeObject<Signature>(tokenDecrypt);

                    //校验签名的有效时间是否合法
                    if (signature.iat > SystemUtils.timeToTimeSpan(DateTime.Now) || signature.exp < SystemUtils.timeToTimeSpan(DateTime.Now))
                    {
                        return false;
                    }

                    else
                    {
                    //此处我为了省事,大家可自定义修改
                        //查询数据库用户中是否存在此授权信息中的用户
                        string sql = "select * from [dbo].[user] where jobNumber=@aud";
                        List<user> listUser = SqlConnectService.select<user>(sql, signature);
                        if (listUser.Count > 0)
                        {
                            //判断该用户是否有访问此接口的权限
                            for (int i = 0; i < this.roles.Length; i++)
                            {
                                if (signature.role.Contains(this.roles[i]))
                                {
                                    return true;
                                }
                            }
                            
                            return false;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }catch(Exception e) {
                Console.WriteLine(e);
                return false;
            }


        }
                       
    }

最后贴上Controller层的代码

  public class DeptController : ApiController
    {
        [HttpGet]
        [RequestAuthorize(roles = new String[] { "admin", "user" })]
        public Object deptSelect() {
            
            return "此接口直服务于 { admin, user }";
        }

        [HttpGet]
        [RequestAuthorize(roles = new String[] { "qq"})]
        public Object deptSelect1()
        {

            return "";
        }

        /// <summary>
        /// 生成Token
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult getToken() {
            Signature signature = new Signature(new String[] { "admin", "user" },"admin",30);
           return Json<String >(JWTUtils.creatToken(signature));
        }

    }

说明:

1.自己先生成Token
2.将Token写入请求头 记住要加 (Bearer )Bearer 后面有个空格!空格!空格!
3.再接口上方添加 [RequestAuthorize]

	代码小白,仅供大家参考,有问题的可以互相交流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值