艾伟:ASP.NET安全问题--Forms验证(后篇)--实战篇

       验证流程讲述

       我们首先假设一个场景:用户现在已经打开了我们的首页Default.aspx,但是有些资源只能是登录用户才可以看到的,那么如果这个用户想要查看这些资源,那么他就要登录。而且这个用户已经有了一个帐号。(我们本篇主要的话题是身份验证,至于创建用户账户是怎么创建的,我们不关心,方法很多,如直接一个数据库插入就行了!)
 
       我们现在就把我们的一些流程说下:
       1.用户登录,在输入框中输入用户名和密码信息
       2.点击登录按钮后,到数据库中查询该用户是否存在
       3 如果存在,服务器端代码就创建一个身份验证的票据,保存在cookie中,然后发送到客户端的浏览器
       4.用户已经有了验证的cookie,那么就页面就跳转到用户之前请求的页面

       数据库准备

       那么下面我们就开始详细讲述:
       首先,我们我们肯定要先得创建一个数据库,我们就取名为Login表,创建一个用户信息表,我们在在表中建立三个字段UserName,UserPassword,UserRole(大家可以创建更多字段,我这里只是演示,大家可以扩展的).  至于表中的数据,大家自己随便插入几条!
 
       代码编写
       因为我们常常要验证用户,所以我们把验证用户的代码写成一个方法放在App_Code目录下的Helpers.cs类中
       代码如下:

验证代码
public static bool ValidateUser(string username, string password)
{

      
    SqlConnection con = new SqlConnection();
    con.ConnectionString =
        ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString;

    SqlCommand com = new SqlCommand();
    com.Connection = con;
    com.CommandText = “Select Count(*) From Users Where Username=@Username and UserPassword=@Password”;

    com.Parameters.AddWithValue(“@Username”, username);
    com.Parameters.AddWithValue(“@Password”, password);
    con.Open();

    int cnt = (int)com.ExecuteScalar();
    con.Close();

    return (cnt > 0);
}

      然后我们就创建一个登录的页面Login.aspx,在页面上面放入两个TextBox,分别用来供用户输入用户名和密码。

      放上一个按钮,用来登录。

      回到Helpers.cs中,我再添加一个方法,来获取用户的角色:

Code
public static string  GetRoleForUser(string username )
{
        //创建链接
    SqlConnection con = new SqlConnection();
    con.ConnectionString =
        ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString;

    SqlCommand com = new SqlCommand();
    com.Connection = con;

        //执行命令
    com.CommandText = “Select UseRole m Users Where Username=@Username;
    com.Parameters.AddWithValue(“@Username”, username);
         
    con.Open();

        //返回结果
    string userRole= (string)com.ExecuteScalar();

    con.Close();
         
}

      为了启动Forms验证,我们还得到web.config文件中配置,如下:

authentication mode=”Forms”>
    =”.mycookie” path=”/” loginUrl=”Login.aspx” protection=”All”
timeout=”40” />
authentication>

      并且不允许匿名用户访问我们的网站 :

<authorization>
  <deny users=”?”/>
>

      然后我们就开始在Login.aspx的登录按钮下面写代码了:

      基本思想如下:

      1.验证用户是否存在,

      2.如果存在,同时获取用户的角色

      3.创建身份验证票据和cookie,并且发送到客户端的浏览器中

     代码都加了注释,通过之前的基础,相信大家可以对下面的代码没有问题。

Code
Code
protected void LoginCallback(object sender, EventArgs e)
{
    if (Helpers.ValidateUser(UserName.Text, Password.Text))
    {
                //获取用户的角色
        string     rolenames = Helpers.GetRolesForUser(UserName.Text);
    
                //创建身份验证票据
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                UserName.Text, DateTime.Now, DateTime.Now.AddSeconds(40), false, roles);

                //加密票据
        string encryptedTicket = FormsAuthentication.Encrypt(ticket);

                //创建新的cookie
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
               
                //把加密后的票据信息放入cookie
        cookie.Value = encryptedTicket;

                //把cookie添加到响应流中
        Response.Cookies.Add(cookie);

                //把cookie发送到客户端
        Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,false),true);

    }
}

      好了,现在如果我们正确的输入用户名和密码,那么我们的浏览器中就有了身份验证的cookie了,现在我们的页面就要马上从原来的Login.aspx转向到Default.aspx页面了,我们现在把这个转向的过程在头脑中把它慢速化,因为我们要分析这个过程。

       在Login.aspx转向到Default.aspx页面跳转的过程中,其实我们在请求Default.aspx页面,这个我们之前请求的过程没有任何的区别,也是一样要经历ASP.NET的一些生命周期,但是这次我们的浏览器中已经有了身份验证的cookie,ASP.NET运行时在处理,在处理Application_AuthenticateRequest事件时就要解析我们的cookie了。其实在之前我们登录之前,在这个事件代码中也解析了cookie的,只是那时候没有找到cookie而以。

       Application_AuthenticateRequest事件的代码中,其实就是解析cookie,然后把用户的身份标识,并且把用户的身份信息保存起来:

Code
Code
Code
void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpApplication app = (HttpApplication)sender;

        //获取身份验证的cookie
    HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (cookie != null)
    {
        string encryptedTicket = cookie.Value;

                //解密cookie中的票据信息
        FormsAuthenticationTicket ticket =
            FormsAuthentication.Decrypt(encryptedTicket);

                //获取用户角色信息
        string[] roles = new string[]{ticket.UserData.toString()};

               //创建用户标识
        FormsIdentity identity = new FormsIdentity(ticket);

                //创建用户的主体信息
        System.Security.Principal.GenericPrincipal user =
        new System.Security.Principal.GenericPrincipal(identity, roles);
        app.Context.User = user;
    }
}

      我们看到最后一行代码:app.Context.User = user;,把用户的身份以及角色信息保存在了User属性中。

      我们就可以在页面中通过如下方法判断用户是否登录了:

 if (Page.User.Identity.IsAuthenticated)
  {
                        //
  }

      用下面的方法判断用户是否属于某个角色:

if (Page.User.IsInRole("Admin")
{
     //
}

      其实这个我们之前讲过了的Identity,IPrincipal概念有关,不清楚的可以看看之前的文章!

      代码到这里,今天也写完了,有关身份验证的问题就要讲完了,还差一个问题没有讲述:自定义身份验证以及开发自定义的HttpModule.

      之后的的文章将讲述授权的问题。

时间: 2024-10-27 02:34:34

艾伟:ASP.NET安全问题--Forms验证(后篇)--实战篇的相关文章

ASP.NET安全问题--Forms验证(后篇)--实战篇

今天话题如下: 验证流程讲述 数据库准备 代码编写 验证流程讲述 我们首先假设一个场景:用户现在已经打开了我们的首页Default.aspx,但是有些资源只能是登录用户才可以看到的,那么如果这个用户想要查看这些资源,那么他就要登录.而且这个用户已经有了一个帐号.(我们本篇主要的话题是身份验证,至于创建用户账户是怎么创建的,我们不关心,方法很多,如直接一个数据库插入就行了!) 我们现在就把我们的一些流程说下: 1.用户登录,在输入框中输入用户名和密码信息 2.点击登录按钮后,到数据库中查询该用户是

asp.net 基于forms验证的目录角色权限的实现_实用技巧

但是我在使用过程中,发现针对角色的控制并不是那么容易,通过在网上查找资料,终于解决这个问题.下面将主要的注意事项列出来.1.配置文件中,角色的allow项要放在deny项的前面,users要配置为*,而不是? 代码 复制代码 代码如下: <location path="Doctors"> <system.web> <authorization> <allow roles="doctors"/> //这个在前 <d

使用asp.net 的Form验证后,jquery-easyui执行报错

问题描述 根目录下的配置文件如下:<authenticationmode="None"><formsloginUrl="~/Login.aspx"name=".ASPXAUTH"timeout="2880"></forms></authentication>管理角色文件夹下的配置文件:<system.web><authorization><denyu

ASP.NET数据绑定之DataList控件实战篇_实用技巧

上篇文章大概讲了DataList的一些基础知识,掌握这些知识在将来的应用中起到很大的作用,现在我们就开始讲上篇文章中说的基础知识做一个小例子.     首先,我机子的数据库中有一张person表,如下图所示. 现在,我们用DataList控件将表中的信息显示出来,并可以在DataList控件上对数据库中的表进行编辑操作.     1.首先用vs创建web应用程序,添加web窗体,在web窗体内拉入DataList控件,右击控件,选择编辑项模板,在这里我们能看到四个模板,其中两个是Selected

艾伟:ASP.NET安全问题--Forms验证的具体介绍(上篇)

本篇的话题如下: Forms验证的工作原理 Forms验证中的API Forms验证的工作原理 我们知道,Forms验证主要是基于cookie的,说白一点就是:把用户信息保存在cookie中,然后发送到客户端:再就是解析客户端的发送了的cookie信息,进行解析,然后进行验证.关于cookieless的工作原理和方法,我这里不赘述,大家可以参看我的另外的一片文章:浅谈ASP.NET内部机制(一). 当匿名用户请求一个需要验证后才能访问的资源和页面的时候,那么如果采用了Forms验证,那么URL授

艾伟_转载:学习 ASP.NET MVC (第四回)实战篇

本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回)实战篇 学习 ASP.NET MVC (第五回)理论篇 我们继续ASP.NET MVC之旅.上文中我们实现了对User信息的展示,详细信息的列表,还有错误页的实现.本文继续完成添加,修改,删除的操作.首先我们来完成Controller的代码: Code//        // GET: /Users

艾伟_转载:学习 ASP.NET MVC (第一回)理论篇

本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回)实战篇 学习 ASP.NET MVC (第五回)理论篇 MVC三种角色:--Model:用于存储数据的组件--View:根据Model数据进行内容展示的组件--Controller:接受并处理用户指令(操作Model),选择一个View并输出内容.Controller对View进行引用,但是View

ASP.NET 2.0验证cookie详解

对于ASP.NET Forms验证,想必大家都非常的熟悉.然而,在控制用户的(过期时间)expired time的时候,你是否遇到过一些奇怪的现象呢?虽说只是一个小小的cookie,但是其中可能有很多的东西你都不知道.今天我将和大家详细讨论一下cookie的注意点. 在ASP.NET 的Forms验证中,通常我们会使用ASP.NET自带的Login控件来进行验证.同时,在web.config文件中,我们所有的Forms设置都设为默认.现在,问题就来了. 1) 为什么我明明点了"Remember

学习 ASP.NET MVC (第四回)实战篇

本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回)实战篇 学习 ASP.NET MVC (第五回)理论篇 我们继续ASP.NET MVC之旅.上文中我们实现了对User信息的展示,详细信息的列表,还有错误页的实现.本文继续完成添加,修改,删除的操作.首先我们来完成Controller的代码: Code //         // GET: /Use