欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# MVC 基于From的身份验证

程序员文章站 2022-05-13 22:51:03
前言 昨天和一个技术比较好的前辈聊了聊,发现有的时候自己的学习方式有些问题,不知道有没有和我一样的越学习越感觉到知识的匮乏不过能认识到这个问题的同学们,也不要太心急路是一步一步走的饭是一口一口吃的认识到错误才能更高的改进错误,脚踏实地只要有上劲学习的心,终会有所成就。认识到自己薄弱的地方进行学习,要 ......

前言

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

什么是身份验证

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

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

身份验证是什么?验证和授权。为什么要使用?加强用户体验效果。能解决什么问题?节省用户时间避免重复性动作。

form身份验证思路

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

建立basecontroller

建立basecontroller继承controller,然后在其他controller中用basecontroller作为父类来继承。我们在base中实现from设置ticket和写入cooike信息等操作。

        /// <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>配置节如下所示:

<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" />。下面依次介绍一下各种属性:

  • 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来进行测试

    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来进行写入我们的信息。

C#  MVC 基于From的身份验证

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

C#  MVC 基于From的身份验证

 

 浏览器中可以看到我们使用的cooike,这就是我们刚刚添加的。

C#  MVC 基于From的身份验证