Asp.Net实现FORM认证的一些使用技巧(必看篇)(4)

以上实现了对不同目录按用户的访问限制。但是一般来说,一个网站系统的用户会很多,如果一直使用精确到用户的访问控制,则会造成设置Web.config的工作量加大。

而一般,我们会将用户分到不同的用户组来进行权限控制,因此,我们也可以配置Web.config实现按角色来控制不同的目录的访问权限。

首先,我们在根目录下再增加一个目录ManageUsers,在此文件夹内也增加页面UserInfo.aspx用来展现登录用户信息。此目录将模拟控制Users组的用户,文件夹ManageAdmin将模拟控制Administrators组的用户。

然后,在目录ManageUsers增加Web.config文件,配置内容如下:

<configuration> <appSettings/> <connectionStrings/> <system.web> <authorization> <allow roles="Users"></allow> <deny users="*"></deny> </authorization> </system.web> </configuration>

再将文件夹ManageAdmin下的Web.config文件的<allow users="Admin"></allow>改成<allow roles="Administrators"></allow>

最后,修改代码。

1、注意,我们在模拟用户信息的时候,有这么一句,user.Roles ="Administrators,Users";也就是用户Admin具备两种角色

2、为模拟Users组的用户登录,我们再添加如下代码:

if (this.TextBox1.Text == "User1" && this.TextBox2.Text == "111111") { // 加密UserInfo UserInfo user = new UserInfo(); user.Id = 2; user.Name = this.TextBox1.Text; user.Password = this.TextBox2.Text; user.RealName = "普通用户1"; user.Roles = "Users"; string strUser = Serialize.Encrypt<UserInfo>(user); // 设置Ticket信息 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, user.Name, DateTime.Now, DateTime.Now.AddMinutes(20), false, strUser); // 加密验证票据 string strTicket = FormsAuthentication.Encrypt(ticket); // 使用新userdata保存cookie HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strTicket); cookie.Expires = ticket.Expiration; this.Response.Cookies.Add(cookie); this.Response.Redirect("Default.aspx"); }

这样,我们登录时,输入“Admin”和“User1”的时候,就可以模拟不同角色的用户登录了。

3、Forms基于角色的验证的内部机制是,将角色的属性也设置到了Context.User中,这里也需要手工代码处理一下。  

首先,为了支持基于角色的验证,我们每进入一个页面都需要将角色信息设置到Context.User中,那么最好的办法就是在Global.asax 文件中的Application_AuthenticateRequest方法中设置。

Application_AuthenticateRequest方法,是在每次验证请求时触发,它与另外一个方法Application_BeginRequest的区别就在于,Application_AuthenticateRequest方法内,能够访问Context.User.Identity,而Application_BeginRequest则无法访问。

我们在根目录添加一个Global.asax 文件,增加如下代码:

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { if (this.Context.User != null) { if (this.Context.User.Identity.IsAuthenticated) { if (this.Context.User.Identity is FormsIdentity) { string strUser = ((FormsIdentity)this.Context.User.Identity).Ticket.UserData; string[] roles = Serialize.Decrypt<UserInfo>(strUser).Roles.Split(','); this.Context.User = new GenericPrincipal(this.Context.User.Identity, roles); } } } }

此处,主要代码就是将Context.User.Identity强制转换为FormsIdentity类的对象,通过访问Ticket属性的UserData属性,获得被序列化后的对象的字符串,最后用方法Serialize.Decrypt<UserInfo>(strUser)将字符串反序列化成对象,再将UserInfo对象的Roles属性以“,”为分隔符分隔成角色数组,再用Context.User.Identity和角色数组生成一个新的GenericPrincipal对象,赋值给Context.User ,则Context.User 为已经设置好角色的验证对象。

按照我们的设置,Admin用户能访问两个目录,而User1用户,则只能访问ManageUsers一个目录。

第六步:集中管理Web.config文件

目录的访问权限控制,是按用户还是按角色,一般由具体业务决定。

但是,随着目录的增多,每个目录下都存在一个Web.config文件,管理起来特别不方便。

通过上面提到过的location节的path属性,我们可以实现Web.config配置的统一管理。我们可以将各个文件或目录的配置都放置在根目录的Web.config文件内,代码如下:

<configuration> <appSettings/> <connectionStrings/> <location path ="Register.aspx"> <system.web> <authorization> <allow users="*"/> </authorization> </system.web> </location> <location path ="ManageAdmin"> <system.web> <authorization> <allow roles="Administrators"></allow> <deny users="*"></deny> </authorization> </system.web> </location> <location path ="ManageUsers"> <system.web> <authorization> <allow roles="Users"></allow> <deny users="*"></deny> </authorization> </system.web> </location> <system.web> <!-- 这里放置原来根目录 Web.config 的内容,就不列出来了 --> </system.web> </configuration>

结尾:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjyjxg.html