Asp.net Form登陆认证的回顾学习

  asp.net网站中,我最常用的就是Form认证了,在实现登陆时,利用Form认证实现用户的访问权限,哪些页面是可以匿名登陆,哪些页面需要认证后才能访问,哪些页面不能访问等等权限。我还可在登陆时,使用FormsAuthenticationTicket 来记住登陆信息来实现网站记住当前登陆者的信息。

1:authentication节点

  在新建的asp.net网站,在web.config文件中,我们可以找到authentication节点

<!--修改验证模式为Forms-->
 <authentication mode="Forms">
 <forms loginUrl="~/Login.aspx" name="HotelUser" defaultUrl="Default.aspx"></forms>
</authentication>
 <!--禁止匿名登陆-->
<authorization>
 <deny users="?"/>
</authorization>

在authorization节点中“allow”表示允许,“*”表示所有用户,‘“deny”表示拒绝的意思,“?”表示匿名用户,这里表示根目录下所有的文件和所有的子目录都不能匿名访问,Login.aspx除外。

2:在web.config中,Location节点的使用。

  假如我们在MVC中添加一个Area(Admin)来实现网站后台登陆,我们也可以在这个web.config来实现“Admin”后台登陆的控制。

<location path="admin">
<system.web>
<authorization>
<allow roles="admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>

web.config的设置将作用于所在目录的所有文件及其子目录下的文件。通过loaction节点的path属性指定admin域页面。它表达的意思是拒绝所有用户登陆,除了角色是"admin"的用户。我们还可以使用location节点指向某个具体的页面。

<location path="Register.aspx">
  
<system.web>
     
<authorization>
       
<allow users="*"/>
     
</authorization>
  
</system.web>
</location>

3:Forms验证机制;

  Forms验证在内部的机制是,把用户数据加密后保存在一个基于cookie的票据FormsAuthenticationTicket中,通过RedirectFromLoginPage方法或者SetAuthCookie方法实现了ticket和Cookie的设置,也就是设置了context.User的值,Cookie的属性是在Web.config的<forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" path="/" timeout="20"/>中设置的,因为是经过特殊加密的,所以是比较安全的。

   .net还留了用用户自定义的方法,可以吧Userdata信息传入到Ticket中,当我们需要这些信息时,可以通过Ticket的UserData属性得到。

if (this.TextBox1.Text == "Admin" && this.TextBox2.Text == "123456")
        {
            
// 加密UserInfo
            UserInfo user = new UserInfo();
            user.Id 
= 1;
            user.Name 
= this.TextBox1.Text;
            user.Password 
= this.TextBox2.Text;
            user.RealName 
= "系统管理员";
            user.Roles 
= "Administrators,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");
        }

UserInfo是我们自定义的登陆者信息的类

[Serializable]
public class UserInfo
{
    
//用户登录信息
    private int _nId;
    
private string _sRealName;
    
private string _sName;    
    
private string _sPassword;
    
private string _sRoles;

    
public int Id
    {
        
get { return this._nId; }
        
set { this._nId = value; }
    }
    
public string RealName
    {
        
get { return this._sRealName; }
        
set { this._sRealName = value; }
    }
    
public string Name
    {
        
get { return this._sName; }
        
set { this._sName = value; }
    }
    
public string Password
    {
        
get { return this._sPassword; }
        
set { this._sPassword = value; }
    }
    
public string Roles
    {
        
get { return this._sRoles; }
        
set { this._sRoles = value; }
    }

    
public UserInfo()
    {        
    }
}

 

记得要在此类加上系列化的标记我们手动设置了一个UserInfo的对象,string strUser = Serialize.Encrypt<UserInfo>(user) 是将对象序列化成字符串的一个方法。

string strTicket = FormsAuthentication.Encrypt(ticket)将票据加密成字符串,最后HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strTicket) 生成Cookie;FormsAuthentication.FormsCookieName获取的就是Web.config中配置的Cookie名称,也就是默认验证时产生的Cookie;

获取登陆信息时,我们可以在AppCode中创建一个页面基类,LoginBasePage;

public class LoginBasePage : Page
{
    
protected UserInfo LoginUser
    {
        
get
        {
            
string strUser = ((FormsIdentity)this.Context.User.Identity).Ticket.UserData;

            
return Serialize.Decrypt<UserInfo>(strUser);               
        }
    }

    
public LoginBasePage()
    {
        
//
        
// TODO: 在此处添加构造函数逻辑
        
//
    }
}

其他页面继承与这个类,就可以拿到LoginUser的信息了。

4:实现不同角色的权限控制;

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

 

表示允许角色为Users的用户可以访问,我们在登陆时user.Roles = "Administrators,Users"表示admin具有两种角色。

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);
                }
            }
        }
    }

附加:本笔记只为自己学习使用,参照了http://www.cnblogs.com/Showshare/archive/2010/07/09/1772886.html这篇文章。

 

posted @ 2014-03-24 09:49  小菜?大神?  阅读(294)  评论(0编辑  收藏  举报