C# MVC 基于From的身份验证

前言

昨天和一个技术比较好的前辈聊了聊,发现有的时候本身的学习方式有些问题,不知道有没有和我同样的越学习越感受到知识的匮乏不过能认识到这个问题的同窗们,也不要太心急路是一步一步走的饭是一口一口吃的认识到错误才能更高的改进错误,脚踏实地只要有上劲学习的心,终会有所成就。认识到本身薄弱的地方进行学习,要清楚学习的目的呀调理清晰:这个是什么?为何要这样?能解决什么问题?入正题吧。web

什么是身份验证

不少网站都有登陆对话框,让事先已经注册的用户验证,以便为他们提供个性化的服务等。能够把这个过程看做是两件事情的发生:验证和受权!登录的做用是验证请求登录的用户是否合法,而受权则是验证合法的用户在请求资源时,根据他们的权限决定是访问仍是拒绝。浏览器

举个例子:咱们已经在一个网站上登陆了,你刚把网页关闭发现又要使用这个网站因而乎你又打开了浏览器而后输入了网址,这个时候你发现还要让你登陆才能进行操做。频繁的这样是失去用户极大的体验效果因此这个时候就用到了身份验证。缓存

身份验证是什么?验证和受权。为何要使用?增强用户体验效果。能解决什么问题?节省用户时间避免重复性动做。安全

Form身份验证思路

用户要浏览须要权限的页面,此时,安全机制先启动,检查当前用户请求是否持有用户票据的Cookie如此Cookie存在:解析Cookie中的票据信息,得到用户角色,建立用户标识或者对象。不然:认为用户无权浏览该页面,跳转至登入页面,登入成功后重定向到所请求页面。服务器

创建BaseController

创建BaseController继承Controller,而后在其余Controller中用BaseController做为父类来继承。咱们在Base中实现From设置Ticket和写入Cooike信息等操做。cookie

        /// <summary>
        /// 保存用户登录信息
        /// </summary>
        public void WriteUserInfoToCookie(UserInfo userinfo)
        {
            var jss = new JavaScriptSerializer();
            var logonInfo = jss.Serialize(userinfo);

            //设置Ticket信息
            var ticket = new FormsAuthenticationTicket(1, userinfo.Name, DateTime.Now,
                                                       DateTime.Now.AddDays(1), false,
                                                       logonInfo);
            //加密验证票据
            var strTicket = FormsAuthentication.Encrypt(ticket);
            //保存cookie
            SetCookie(FormsAuthentication.FormsCookieName, strTicket, ticket.Expiration, true);
        }

        /// <summary>
        /// 写入Cooike
        /// </summary>
        /// <param name="cookiename"></param>
        /// <param name="value"></param>
        /// <param name="expires"></param>
        /// <param name="isSetExpires"></param>
        public static void SetCookie(string cookiename, string value, DateTime expires, bool isSetExpires)
        {
            var request = System.Web.HttpContext.Current.Request;
            var response = System.Web.HttpContext.Current.Response;
            var cookie = request.Cookies[cookiename] ?? new System.Web.HttpCookie(cookiename);
            cookie.Domain = FormsAuthentication.CookieDomain;
            if (value == null)
            {
                RemoveCookie(cookiename);
            }
            else
            {
                cookie.Value = value;

                //true表明客户端只能读,不能写。只有服务端可写,防止被篡改
                cookie.HttpOnly = true;

                if (isSetExpires)
                {
                    cookie.Expires = expires;
                }
            }
            response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 移除指定名称的cookie对象中的集合对
        /// </summary>
        /// <param name="cookieName">cookie名称</param>
        public static void RemoveCookie(string cookieName)
        {
            var cookie = System.Web.HttpContext.Current.Request.Cookies[cookieName];
            var response = System.Web.HttpContext.Current.Response;
            if (cookie == null) return;
            cookie.Values.Clear();
            cookie.Domain = FormsAuthentication.CookieDomain;
            cookie.Expires = DateTime.Now.AddDays(-10000d);
            response.Cookies.Add(cookie);
        }

创建实体做为用户登陆信息和写入Cookie

    public class UserInfo
    {
        public string Name { get; set; }

        public string PassWord { get; set; }

    }

配置WebConfig

  <system.web>
    <authentication mode="Forms">
      <forms name="test" protection="All" loginUrl="~/account/default" timeout="2880" />
    </authentication>
  </system.web>

Forms Authentication相关的配置

有些同窗会蒙圈为啥会配置authentication,下面咱们看下他们的信息
在web.config文件中,<system.web>/<authentication>配置节用于对验证进行配置。为<authentication>节点提供mode="Forms"属性能够启用Forms Authentication。一个典型的<authentication>配置节以下所示:less

<authentication mode="Forms">
     <forms
         name=".ASPXAUTH"
         loginUrl="login.aspx"
         defaultUrl="default.aspx"
         protection="All"
         timeout="30"
         path="/"
         requireSSL="false"
         slidingExpiration="false"
         enableCrossAppRedirects="false"
         cookieless="UseDeviceProfile"
         domain=""
     />
</authentication>

以上代码使用的均是默认设置,换言之,若是你的哪项配置属性与上述代码一致,则能够省略该属性。例如<forms name="MyAppAuth" />。下面依次介绍一下各类属性:dom

  • name——Cookie的名字。Forms Authentication可能会在验证后将用户凭证放在Cookie中,name属性决定了该Cookie的名字。经过FormsAuthentication.FormsCookieName属性能够获得该配置值(稍后介绍FromsAuthentication类)。
  • loginUrl——登陆页的URL。经过FormsAuthentication.LoginUrl属性能够获得该配置值。当调用FormsAuthentication.RedirectToLoginPage()方法时,客户端请求将被重定向到该属性所指定的页面。loginUrl的默认值为“login.aspx”,这代表即使不提供该属性值,ASP.NET也会尝试到站点根目录下寻找名为login.aspx的页面。
  • defaultUrl——默认页的URL。经过FormsAuthentication.DefaultUrl属性获得该配置值。
  • protection——Cookie的保护模式,可取值包括All(同时进行加密和数据验证)、Encryption(仅加密)、Validation(仅进行数据验证)和None。为了安全,该属性一般从不设置为None。
  • timeout——Cookie的过时时间。
  • path——Cookie的路径。能够经过FormsAuthentication.FormsCookiePath属性获得该配置值。
  • requireSSL——在进行Forms Authentication时,与服务器交互是否要求使用SSL。能够经过FormsAuthentication.RequireSSL属性获得该配置值。
  • slidingExpiration——是否启用“弹性过时时间”,若是该属性设置为false,从首次验证以后过timeout时间后Cookie即过时;若是该属性为true,则从上次请求该开始过timeout时间才过时,这意味着,在首次验证后,若是保证每timeout时间内至少发送一个请求,则Cookie将永远不会过时。经过FormsAuthentication.SlidingExpiration属性能够获得该配置值。
  • enableCrossAppRedirects——是否能够将以进行了身份验证的用户重定向到其余应用程序中。经过FormsAuthentication.EnableCrossAppRedirects属性能够获得该配置值。为了安全考虑,一般老是将该属性设置为false。
  • cookieless——定义是否使用Cookie以及Cookie的行为。Forms Authentication能够采用两种方式在会话中保存用户凭据信息,一种是使用Cookie,即将用户凭据记录到Cookie中,每次发送请求时浏览器都会将该Cookie提供给服务器。另外一种方式是使用URI,即将用户凭据看成URL中额外的查询字符串传递给服务器。该属性有四种取值——UseCookies(不管什么时候都使用Cookie)、UseUri(从不使用Cookie,仅使用URI)、AutoDetect(检测设备和浏览器,只有当设备支持Cookie而且在浏览器中启用了Cookie时才使用Cookie)和UseDeviceProfile(只检测设备,只要设备支持Cookie无论浏览器是否支持,都是用Cookie)。经过FormsAuthentication.CookieMode属性能够获得该配置值。经过FormsAuthentication.CookiesSupported属性能够获得对于当前请求是否使用Cookie传递用户凭证。
  • domain——Cookie的域。经过FormsAuthentication.CookieDomain属性能够获得该配置值。

验证Ing

咱们建立个Controller,我创建的是HomeController来进行测试ide

    public class HomeController : BaseCntroller
    {
        public ActionResult Index()
        {
            if (User.Identity.IsAuthenticated)
            {
                var strUser = ((FormsIdentity)User.Identity).Ticket.UserData;
                var _loginInfo = new UserInfo();
                if (strUser.Contains("{") && strUser.Contains("}"))
                {
                    var jss = new JavaScriptSerializer();
                    _loginInfo = jss.Deserialize<UserInfo>(strUser);
                }
                else
                {
                    //或者能够从缓存里面取出
                }
                return Json(new { result = true });
            }
            else
            {
                UserInfo user = new UserInfo();
                user.Name = "焦海涛";
                user.PassWord = "123456";
                WriteUserInfoToCookie(user);
            }
            return View();
        }
    }

刚进来咱们能够看到User的identity是flase说明咱们没有登陆过。那么确定是else来进行写入咱们的信息。学习

设置tick信息而后进行写入cooike

 

 浏览器中能够看到咱们使用的Cooike,这就是咱们刚刚添加的。

相关文章
相关标签/搜索