ASP.NET Forms 身份验证
2005-06-23 14:32 胖子 阅读(2029) 评论(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>
<UserEmail>jchen@mail.com</UserEmail>
<UserPassword>
BA56E5E0366D003E98EA1C7F04ABF8FCB3753889
</UserPassword>
</Users>
</Users>
应用程序根目录配置文件 (Web.config)
<system.web>
<authentication mode="Forms">
<forms name="FORMSAUTHCOOKIE" loginUrl = "logon.aspx" />
</authentication>
<!-- 拒绝未经身份验证的用户访问此目录 -->
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
AddUser 目录配置文件 (Web.config)
这些设置允许任何人查看 AddUser.aspx 页。
<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"];
if( 0 != 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