zoukankan      html  css  js  c++  java
  • jwt的ASP.NET MVC 身份验证

    Json Web Token(jwt)     

              一种不错的身份验证及授权方案,与 Session 相反,Jwt 将用户信息存放在 Token 的 payload 字段保存在客户端,通过 RSA 加密的方式,保证数据不会被篡改,验证数据有效性。

    详细请参考jwt.io。 我现在还是一枚小白,希望能帮助更多的小白成长。因此文章都是一些比较简单的使用过程,文字讲解较少,怕误人子弟。

    小白成长为大牛过程:知其然而不知其所引然

                                     再知其然而知其所引然

    1. 开发环境如下

    vs2017+ASP.NET MVC 5+.NET FrameWork4.5.2

    2. 在nuget上先添加封装了jwt使用的框架

    因为环境是.NET FrameWork4.5.2   所以我采用3.0.1版本

    11

     3.封装一个JWT帮助类

    创建实体类  UserInfo   

    public string UserName { get; set; }

    public string Pwd { get; set; }

        public class JwtHelp
        {
    
            //私钥  web.config中配置
            //"GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
            private static string secret = ConfigurationManager.AppSettings["Secret"].ToString();
    
            /// <summary>
            /// 生成JwtToken
            /// </summary>
            /// <param name="payload">不敏感的用户数据</param>
            /// <returns></returns>
            public static string SetJwtEncode(Dictionary<string, object> payload)
            {
    
                //格式如下
                //var payload = new Dictionary<string, object>
                //{
                //    { "username","admin" },
                //    { "pwd", "claim2-value" }
                //};
    
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
    
                var token = encoder.Encode(payload, secret);
                return token;
            }
    
            /// <summary>
            /// 根据jwtToken  获取实体
            /// </summary>
            /// <param name="token">jwtToken</param>
            /// <returns></returns>
            public static UserInfo GetJwtDecode(string token)
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
                var userInfo = decoder.DecodeToObject<UserInfo>(token, secret, verify: true);//token为之前生成的字符串
                return userInfo;
            }
        }
    }

    4.创建JwtController  生成jwtToken看看效果 

    Get 请求需要改成这样

    return Json(result,JsonRequestBehavior.AllowGet);

    public class JwtController : Controller
        {
            // GET: Jwt
            public ActionResult Index()
            {
                return View();
            }
    
            /// <summary>
            /// 创建jwtToken
            /// </summary>
            /// <param name="username"></param>
            /// <param name="pwd"></param>
            /// <returns></returns>
            public ActionResult CreateToken(string username, string pwd)
            {
    
                DataResult result = new DataResult();
    
                //假设用户名为"admin",密码为"123"  
                if (username == "admin" && pwd == "123")
                {
    
                    var payload = new Dictionary<string, object>
                    {
                        { "username",username },
                        { "pwd", pwd }
                    };
    
                    result.Token = JwtHelp.SetJwtEncode(payload);
                    result.Success = true;
                    result.Message = "成功";
                }
                else
                {
                    result.Token = "";
                    result.Success = false;
                    result.Message = "生成token失败";
                }
    
                return Json(result);
    //get请求需要修改成这样
           //return Json(result,JsonRequestBehavior.AllowGet); } }

    5.我喜欢postMan测试神器   你值得拥有

    22

     6.AuthorizeAttribute

    接下来,我们需要编写有关权限控制及token解析有关的代码。

    所有操作都在Home里面  将受限Action或Controller打上标签, 所有访问都想先权限验证通过后才能访问

    编写一个继承AuthorizeAttribute实现类,根据实体类是否相等。

    我先简单描述下程序执行过程

    1.进入验证入口->验证核心代码->

    1.返回false进入验证处理失败

    2.返回true进入访问的controller/action里面

    public class MyAuthorizeAttribute : AuthorizeAttribute
        {
            /// <summary>
            /// 验证入口
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                base.OnAuthorization(filterContext);
            }
    
            /// <summary>
            /// 验证核心代码
            /// </summary>
            /// <param name="httpContext"></param>
            /// <returns></returns>
            protected override bool AuthorizeCore(HttpContextBase httpContext)
            {
    
    
                //前端请求api时会将token存放在名为"auth"的请求头中
                var authHeader = httpContext.Request.Headers["auth"];
                if (authHeader == null)
                {
                    httpContext.Response.StatusCode = 403;
                    return false;
                }
    
    
                var userinfo = JwtHelp.GetJwtDecode(authHeader);
                //举个例子  生成jwtToken 存入redis中    
                //这个地方用jwtToken当作key 获取实体val   然后看看jwtToken根据redis是否一样
                if (userinfo.UserName == "admin" && userinfo.Pwd == "123")
                    return true;
    
                httpContext.Response.StatusCode = 403;
                return false;
            }
    
            /// <summary>
            /// 验证失败处理
            /// </summary>
            /// <param name="filterContext"></param>
            protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
            {
    
                base.HandleUnauthorizedRequest(filterContext);
                if (filterContext.HttpContext.Response.StatusCode == 403)
                {
                    filterContext.Result = new RedirectResult("/Error");
                    filterContext.HttpContext.Response.Redirect("/Home/Error");
                }
            }
        }

    使用postman  然后再Headers 地方将jswToken 传入进去

    11

    参考资料链接

    https://www.cnblogs.com/lwhkdash/p/6686999.html

    https://www.cnblogs.com/cnki/p/6297182.html

    github下载链接  上述错误,请大家多多包涵。我还是一枚小白。

    https://github.com/yaols/JWT.MvcDemo

  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/xiaobai123/p/9242828.html
Copyright © 2011-2022 走看看