代码改变世界

ASP.NET Forms 身份验证

2005-06-23 14:32  胖子  阅读(2023)  评论(0编辑  收藏  举报

Forms 身份验证

注:贴出来,方便自己日后参考。 出处:MSDN

在此应用程序示例中要用到两个目录(FormsAuth 和 AddUser)和六个文件。它们按下面的方式排列。
\FormsAuth (Web.config, Default.aspx, Logon.aspx, Users.xml)
\FormsAuth\AddUser (Web.config, AddUser.aspx)
(FormsAuth 目录是应用程序根目录。)

在位于 FormsAuth 目录的 Web.config 文件的安全性部分中设置授权,以便只有已验证的用户才可以访问此目录。
身份验证模式设置为 Forms,所以 ASP.NET 将尝试查找附加到该请求的 Cookie。如果没有找到,则将请求重定向到登录页 (Logon.aspx)。客户端用户在登录页中输入所需的凭据(电子邮件名称和密码)。该页将输入的凭据与 XML 文件 (Users.xml) 中的凭据列表相比较。如果找到匹配项,则将请求视为已验证,并将客户重定向到最初请求的资源 (Default.aspx)。如果没有找到匹配项,则将请求重定向到“添加用户”页 (AddUser.aspx)。位于此 AddUser 目录中的 Web.config 文件有设置为允许任何人访问的授权。在这里,刚输入的凭据被编码并添加到 XML 文件 (Users.xml) 中。

用户凭据文件 (Users.xml)
Users.xml 是这样一个文件,它包含已授权访问 Default.aspx 文件(也位于 FormsAuth 目录中)的用户的用户名和密码。Logon.aspx 从此文件读取用户名和密码信息,而 AddUser 进程将用户名和密码信息写入此文件。
在这个简单的示例中,将使用静态 FormsAuthentication.HashPasswordForStoringInConfigFile 方法对密码进行散列运算。
下例显示 Users.xml 文件的默认内容。对于 jchen@mail.com,非哈希密码是 jchenpw

<Users>
    
<Users>
        
<UserEmail>jchen@mail.com</UserEmail>
        
<UserPassword>
            BA56E5E0366D003E98EA1C7F04ABF8FCB3753889
        
</UserPassword>
    
</Users>
</Users>


应用程序根目录配置文件 (Web.config)

<configuration>
  
<system.web>
            
<authentication mode="Forms">
                    
<forms name="FORMSAUTHCOOKIE" loginUrl = "logon.aspx" />
            
</authentication>
            
<!-- 拒绝未经身份验证的用户访问此目录 -->
      
<authorization>
          
<deny users="?"/> 
      
</authorization>
  
</system.web>
</configuration>


AddUser 目录配置文件 (Web.config)
这些设置允许任何人查看 AddUser.aspx 页。

<configuration>
    
<system.web>
        
<authorization>
            
<allow users="*"/> 
        
</authorization>
    
</system.web >
</configuration>


Default.aspx 文件
Default.aspx 文件是默认被请求的、受保护的资源。如果传输的请求具有有效的 Cookie,则它是显示字符串 Hello 和用户的存储电子邮件名称的简单文件。如果 Cookie 未随请求一起传输,则 ASP.NET 将客户自动重定向到 Logon.aspx 页。Default.aspx 还包括一个“注销”按钮,该按钮从客户端删除 Cookie。
FormsAuthentication.SignOut()


Login.aspx 文件

        //创建“数据集”类的新实例。 
        DataSet ds = new DataSet();

        
//读入包含已验证用户名和密码组合的 XML 文件。
    FileStream fs = new FileStream(Server.MapPath("Users.xml"), 
                                  FileMode.Open,FileAccess.Read);
    StreamReader reader 
= new StreamReader(fs);
    ds.ReadXml(reader);
    fs.Close();

        
//创建一个名为 users 的“数据表”的新实例
    DataTable users = ds.Tables[0];

        
//检查登录名和 Users.aspx 中的名称列表之间所存在的任何匹配项。
        
//对于找到的每个匹配项,均在名为 matches 的“数据行”中记录其名称。
        
//注意:为简单起见,此示例要求每个名称都是唯一的,
        
//所以只使用找到的第一个匹配项。
    DataRow[] matches = users.Select(cmd);

        
//检查在前面步骤中找到的每个名称匹配项,
        
//查看对于它们中的任意一个是否存在匹配的密码。 
    if( matches != null && matches.Length > 0 ) 
    
{
                
//如果找到用户名匹配项,则对用户的密码进行散列运算
                
//并将其与存储在 Users.xml 文件中的哈希进行比较。 
        DataRow row = matches[0];
        
string hashedpwd = 
            FormsAuthentication.HashPasswordForStoringInConfigFile
                (UserPass.Value, 
"SHA1");
        String pass 
= (String)row["UserPassword"];
        
if0 != String.Compare(pass, hashedpwd, false) ) 
            
// Tell the user if no password match is found. It is good  
            
// security practice give no hints about what parts of the
            
// logon credentials are invalid.
            Msg.Text = "Invalid Credentials: Please try again.";
        
else 
            
// If a password match is found, redirect the request
            
// to the originally requested resource (Default.aspx).
            FormsAuthentication.RedirectFromLoginPage
                (UserEmail.Value, Persist.Checked);
    }

    
else 
    
{
                
// If no name matches were found, redirect the request to the
                
// AddUser page using a Response.Redirect command.
        Response.Redirect("AddUser/AddUser.aspx");
    }


AddUser.aspx 文件

        //如果该页无效,则通知用户。 
    if!Page.IsValid ) 
    
{
        Msg.Text 
= "Some required fields are invalid.";
        
return;    
    }

    
    
//创建名为 ds 的“数据集”的实例。 
    DataSet ds = new DataSet();
    
//使用 Users.xml 文件的路径初始化名为 userFile 的字符串。 
    String userFile = "../users.xml";
    
//将 XML 文件读入在步骤 b 中创建的 ds“数据集”。 
    FileStream fs = new FileStream(Server.MapPath(userFile),FileMode.Open,FileAccess.Read);
    StreamReader reader 
= new StreamReader(fs);
    ds.ReadXml(reader);
    fs.Close();
        
//对密码进行散列运算并将新名称和哈希密码添加到 ds“数据集”。 
        string hashedpwd =    
    FormsAuthentication.HashPasswordForStoringInConfigFile(UserPass.Value, 
"SHA1");
    DataRow newUser 
= ds.Tables[0].NewRow();
    newUser[
"UserEmail"= UserEmail.Value;
    newUser[
"UserPassword"= hashedpwd;
    ds.Tables[
0].Rows.Add(newUser);
    ds.AcceptChanges();
        
//使用新名称和密码将新的“数据集”写入 XML 文件。 
    fs = new FileStream(Server.MapPath(userFile), FileMode.Create, 
        FileAccess.Write
|FileAccess.Read);
    StreamWriter writer 
= new StreamWriter(fs);
    ds.WriteXml(writer);
    writer.Close();
    fs.Close();


--------------------------
to be continued