构建基于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页面。 注意:测试时注意及时点击安全退出按钮,否则影响测试结果。
--------------------------------------------------------------------------------------------------------------------------------------------------------
|
请发表评论