Forms身份验证基于角色的授权
一 身份验证
在web.config的<authentication>的设置还是一样:
<authentication mode="forms">
<forms name=".ASPXAUTH " loginUrl="/login.aspx" timeout="30" path= "/">
</forms>
</authentication>
/login.aspx验证用户合法性页面中,在验证了用户的合法性后,还要有个取得此用户属于哪些role的过程,这个看各个应用的本身如何设计的了,一般是在数据库中会有个use_role表,可以从数据库中获得此用户属于哪些role,在此不深究如何去获取用户对应的role,最后肯定能够获得的此用户对应的所有的role用逗号分割的一个字符串。
在上面的非基于角色的方法中,我们用了FormsAuthentication.RedirectFromLoginPage 方法来完成生成身份验证票,写回客户端,浏览器重定向等一系列的动作。这个方法会用一些确省的设置来完成一系列的动作,在基于角色的验证中我们不能用这一个方法来实现,要分步的做,以便将一些定制的设置加进来:
1. 首先要根据用户标示,和用户属于的角色的字符串来创建身份验证票
public FormsAuthenticationTicket(
int version, //设为1
string name, //用户标示
DateTime issueDate, //Cookie 的发出时间, 设置为 DateTime.Now
DateTime expiration, //过期时间
bool isPersistent, //是否持久性(根据需要设置,若是设置为持久性,在发出
cookie时,cookie的Expires设置一定要设置)
string userData, //这里用上面准备好的用逗号分割的role字符串
string cookiePath // 设为"/",这要同发出cookie的路径一致,因为刷新cookie
要用这个路径
);
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,"kent",DateTime.Now, DateTime.Now.AddMinutes(30), false,UserRoles,"/") ;
2. 生成身份验证票的Cookie
2.1 将身份验证票加密序列化成一个字符串
string HashTicket = FormsAuthentication.Encrypt (Ticket) ;
2.2 生成cookie
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;
FormsAuthentication.FormsCookieName 是用来获取web.config中设置的身份验证cookie的名字,缺省为" .ASPXAUTH".
若身份验证票中的isPersistent属性设置为持久类,则这个cookie的Expires属性一定要设置,这样这个cookie才会被做为持久cookie保存到客户端的cookie文件中.
3. 将身份验证票Cookie输出到客户端
通过Response.Cookies.Add(UserCookie) 将身份验证票Cookie附加到输出的cookie集合中,发送到客户端.
4. 重定向到用户申请的初试页面.
验证部分代码(这部分代码是在login.aspx页面上点击了登录按钮事件处理代码):
private void Buttonlogin_Click(object sender, System.EventArgs e)
{
string user = TextBoxUser.Text; //读取用户名
string password = TextBoxPassword.Text; //读取密码
if(Confirm(user,password) == true) //confirm方法用来验证用户合法性的
{
string userRoles = UserToRole(user); //调用UserToRole方法来获取role字符串
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,user,DateTime.Now, DateTime.Now.AddMinutes(30), false,userRoles,"/") ; //建立身份验证票对象
string HashTicket = FormsAuthentication.Encrypt (Ticket) ; //加密序列化验证票为字符串
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;
//生成Cookie
Context.Response.Cookies.Add (UserCookie) ; //输出Cookie
Context.Response.Redirect (Context.Request["ReturnUrl"]) ; // 重定向到用户申请的初始页面
}
else
{
// 用户身份未被确认时的代码
}
}
//此方法用来验证用户合法性的
private bool Confirm(string user,string password)
{
//相应的代码
}
//此方法用来获得的用户对应的所有的role用逗号分割的一个字符串
private string UserToRole(string user)
{
//相应的代码
}
二 基于角色访问授权
这里我们要做的是,将客户端保存的身份验证票中UserData中保存的表示角色的信息恢复到在服务端表示用户身份的GenericPrincipal对象中(记住,原来的验证过程中, GenericPrincipal对象只包含了用户信息,没有包含role信息)
一个Http请求的过程中,HttpApplication.AuthenticateRequest事件表示安全模块已建立用户标识,就是此用户的身份在web端已经建立起来, 在这个事件之后我们就可以获取用户身份信息了.
在HttpApplication.ResolveRequestCache事件之前,asp.net开始取得用户请求的页面,建立HttpHandler控制点,这时就已经要验证用户的权限了,所以恢复用户角色的工作只能在HttpApplication.AuthenticateRequest事件和HttpApplication.ResolveRequestCache事件之间的过程中做.
我们选择Application_AuthorizeRequest事件中做这个工作,可以在global.asax文件中处理HttpApplication的所有的事件,代码如下:
protected void Application_AuthorizeRequest(object sender, System.EventArgs e)
{
HttpApplication App = (HttpApplication) sender;
HttpContext Ctx = App.Context ; //获取本次Http请求相关的HttpContext对象
if (Ctx.Request.IsAuthenticated == true) //验证过的用户才进行role的处理
{
FormsIdentity Id = (FormsIdentity)Ctx.User.Identity ;
FormsAuthenticationTicket Ticket = Id.Ticket ; //取得身份验证票
string[] Roles = Ticket.UserData.Split (',') ; //将身份验证票中的role数据转成字符串数组
Ctx.User = new GenericPrincipal (Id, Roles) ; //将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户,这样当前用户就拥有了role信息
}
}
访问者同时具有了user和role信息,就可以据此在web.config中用role来控制用户的访问权限了.