• asp.net Forms身份验证和基于角色的权限访问(转)


    构建基于forms的验证机制过程如下:
     1,设置IIS为可匿名访问和asp.net web.config中设置为form验证
      2,检索数据存储验证用户,并检索角色(如果不是基于角色可不用)
     3,使用FormsAuthenticationTicket创建一个 Cookie并回发到客户端,并存储
      角色到票据中,如:
      FormsAuthentication.SetAuthCookie(Username,true | false)
      cookies保存时间:
      HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName].Expires=DateTime.Now.AddDays(1)
     
      如果需要存储角色,采用:
     FormsAuthenticationTicket authTicket = new
     FormsAuthenticationTicket(
      1, // 版本号。
      txtUserName.Text, // 与身份验证票关联的用户名。
      DateTime.Now, // Cookie 的发出时间。
      DateTime.Now.AddMinutes(20),// Cookie 的到期日期。
      false, // 如果 Cookie 是持久的,为 true;否则为 false。
      UserData ); // 将存储在 Cookie 中的用户定义数据,可以是用户所属角色,
                           // 若角色保存在数据库中,则用User.Roles等方式;
                           // 若不在数据库中,则可以直接写,如“Admin”,"User"等值
      string encryptedTicket = FormsAuthentication.Encrypt(authTicket); //加密
     
      存入Cookie
      HttpCookie authCookie =
      new HttpCookie(FormsAuthentication.FormsCookieName,
      encryptedTicket);
     
      Response.Cookies.Add(authCookie);
     
     4,在 Application_AuthenticateRequest事件中处理程序中(Global.asax)中,使用
      票创建IPrincipal对象并存在HttpContext.User中
      代码:
      HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
      FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);//解密
      string[] roles = authTicket.UserData.Split(new char[]{';'});//根据存入时的格式分解,;或|....
      Context.User = new GenericPrincipal(Context.User.Identity, Roles);//存到HttpContext.User中
     
     判断某个角色验证
      HttpContext.Current.User.IsInRole(roles)
     具体实现
     
     Web.config 文件
     加入节点,name为COOKIE名称,loginUrl为没有通过验证跳转的地址
     <system.web>
      <authentication mode="Forms">
      <forms name="Hstear"
      loginUrl="login.aspx" protection="All" path="/" timeout="40"/>
      </authentication>
     </system.web>
     设置目录访问 path为目录名,roles为票据中的角色名
     发现网上的都说要单独一个WEB.CONFIG文件放在目录中,但实际在根目录中设置即可,单 个文件也一样
     <location path="Admin">
           <system.web>
           <authorization>
           <allow roles="admin"/>
           <deny users="*"/>
           </authorization>
           </system.web>
     </location>

    以下是一个具体实例的步骤:


    1、创建一个网站,结构如下:
    网站根目录
    Admin目录 ----> 管理员目录
    Manager.aspx ----> 管理员可以访问的页面
    Users目录 ----> 注册用户目录
    Welcome.aspx ----> 注册用户可以访问的页面
    Error目录 ----> 错误提示目录
    AccessError.htm ----> 访问错误的提示页面
    default.aspx ----> 网站默认页面
    login.aspx ----> 网站登录页面
    web.config ----> 网站配置文件
    2、配置web.config如下:

    <configuration>
    <system.web>
    <!--设置Forms身份验证--> 
            <authentication mode="Forms"> 
                    <forms loginUrl="Login.aspx" name="MyWebApp.APSXAUTH" path="/" protection="All" timeout="30"/> 
            </authentication> 
            <authorization> 
                    <allow users="*"/> 
            </authorization>
    </system.web>
    </configuration>

    <!--设置Admin目录的访问权限-->
    <location path="Admin"> 
            <system.web> 
                    <authorization> 
                            <allow roles="Admin"/> 
                            <deny users="?"/> 
                    </authorization> 
            </system.web>
    </location>
    <!--设置Users目录的访问权限-->
    <location path="Users"> 
            <system.web> 
                    <authorization> 
                            <allow roles="User"/> 
                            <deny users="?"/> 
                    </authorization> 
            </system.web>
    </location>

    3、在login.aspx页面的登录部分代码如下:

    protected void btnLogin_Click(object sender, EventArgs e)

            //Forms身份验证初始化 
            FormsAuthentication.Initialize(); 
            //验证用户输入并得到登录用户,txtName是用户名称,txtPassword是登录密码 
            UserModel um = ValidUser(txtName.Text.Trim(),txtPassword.Text.Trim()); 
            if (um != null) 
            { 
                    //创建身份验证票据 
                    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, 
                    um.Name, 
                    DateTime.Now, 
                    DateTime.Now.AddMinutes(30), 
                    true, 
                    um.Roles,//用户所属的角色字符串 
                    FormsAuthentication.FormsCookiePath); 
                    //加密身份验证票据 
                    string hash = FormsAuthentication.Encrypt(ticket); 
                    //创建要发送到客户端的cookie 
                    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash); 
                    if (ticket.IsPersistent) 
                    { 
                            cookie.Expires = ticket.Expiration; 
                    } 
                    //把准备好的cookie加入到响应流中 
                    Response.Cookies.Add(cookie);

                    //转发到请求的页面 
                    Response.Redirect(FormsAuthentication.GetRedirectUrl(um.Name,false)); 
            } 
            else 
            { 
                    ClientScriptManager csm = this.Page.ClientScript; 
                    csm.RegisterStartupScript(this.GetType(), "error_tip", "alert('用户名或密码错误!身份验证失败!');", true); 
            }
    }
    //验证用户
    private UserModel ValidUser(string name, string password)

            return new UserService().Validate(name, password);
    }

    4、给网站添加处理程序Global.asax,其中通用身份验证代码如下:

    //改造原来的User,给其添加一个用户所属的角色数据
    protected void Application_AuthenticateRequest(object sender, EventArgs e)

            if (HttpContext.Current.User != null ) 
            { 
                    if (HttpContext.Current.User.Identity.IsAuthenticated) 
                    { 
                            if (HttpContext.Current.User.Identity is FormsIdentity) 
                            { 
                                    FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 
                                    FormsAuthenticationTicket ticket = id.Ticket;

                                    string userData = ticket.UserData; 
                                    string[] roles = userData.Split(','); 
                                    //重建HttpContext.Current.User,加入用户拥有的角色数组 
                                    HttpContext.Current.User = new GenericPrincipal(id, roles); 
                            } 
                    } 
            }
    }

    5、在Admin目录中Manager.aspx页面加载代码如下:
    复制代码 代码如下:
    protected void Page_Load(object sender, EventArgs e)

            //判断通过身份验证的用户是否有权限访问本页面 
            FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 
            //判断通过身份验证的用户是否是Admin角色 
            if (!id.Ticket.UserData.Contains("Admin")) 
            { 
                    //跳转到访问权限不够的错误提示页面 
                    Response.Redirect("~/Error/AccessError.htm", true); 
            }
    }
    //安全退出按钮的代码
    protected void btnExit_Click(object sender, EventArgs e)

            //注销票据 
            FormsAuthentication.SignOut(); 
            ClientScriptManager csm = this.Page.ClientScript; 
            csm.RegisterStartupScript(this.GetType(), "exit_tip", "alert('您已经安全退出了!');", true); 
     }

    6、在Users目录中Welcome.aspx页面加载代码如下:

    protected void Page_Load(object sender, EventArgs e)

            //判断通过身份验证的用户是否有权限访问本页面 
            FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 
            //判断通过身份验证的用户是否是User角色 
            if (!id.Ticket.UserData.Contains("User")) 
            { 
                    //跳转到访问权限不够的错误提示页面 
                    Response.Redirect("~/Error/AccessError.htm", true); 
            }
    }


    //安全退出按钮的代码
    protected void btnExit_Click(object sender, EventArgs e)

            //注销票据 
            FormsAuthentication.SignOut(); 
            ClientScriptManager csm = this.Page.ClientScript; 
            csm.RegisterStartupScript(this.GetType(), "exit_tip", "alert('您已经安全退出了!');", true);
    }

    测试结果:
    数据:
    假设有3个用户,如下:
    ------------------------------------------
    用户名 密码 角色字符串
    ------------------------------------------
    sa sa Admin,User
    admin admin Admin
    user user User
    ------------------------------------------
    测试:
    如果使用admin登录,只能访问Admin目录的Manager.aspx页面;
    如果使用user登录,只能访问Users目录的Welcome.aspx页面;
    使用sa登录,既能访问Admin目录的Manager.aspx页面,又能访问Users目录的Welcome.aspx页面。
    注意:测试时注意及时点击安全退出按钮,否则影响测试结果。

    --------------------------------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    软件工程二人组队开发第一周
    软件工程第五周
    这学期的目标
    软件工程第四周的总结
    二维数组的最大子数组和 时间复杂度:O(n的四次方)
    10.tesseract
    mysql存储过程和函数
    mysql触发器
    9.selenium
    mysql练习
  • 原文地址:https://www.cnblogs.com/hfutwyy/p/2127133.html
Copyright © 2020-2023  润新知