ASP.NET 特定对象的表单身份验证
如何自定义表单身份验证以保护特定目录或页面。
引言
本文将扩展 ASP.NET 表单身份验证的现有知识库,以及如何保护特定的子目录或网页。如果您需要了解什么是表单身份验证,我建议您在其他地方学习它。
问题
如果您使用过表单身份验证,那么您就知道它与 ASP.NET、C# 和 Framework 2.0 结合使用时有多强大。我在开发一个 Web 应用程序并构建一个管理模块来管理网站时遇到了一个问题。通常,我将所有管理页面放在一个名为 "Admin" 的子目录中。本文将向您展示如何使用几乎不需要代码来保护特定的子目录或页面。
解决方案
网站结构
让我们从我们虚构的网站开始,它有许多页面和许多子目录。我们想要的一个子目录是 ~/Admin。
1. Web.config - 保护目录/页面
首先,我们需要保护目录或页面。在根目录的 web.config 文件中,在任何位置添加它,但必须在 configuration
标签内。我通常将其添加到底部
<configuration>
...
<location path="Admin">
<system.web>
<authorization>
<allow users="AdminLogin"/>
<allow users="AdminBackupLogin"/>
<deny users="?" />
</authorization>
</system.web>
</location>
...
</configuration>
如果我们想保护一个页面,我们只需将 "Admin" 更改为 "Page1.aspx" 或 "~/Directory/Page2.aspx"。另外,请注意我已经设置了允许和不允许的用户。
"?" 表示所有未经身份验证的匿名用户。"*" 表示所有人。请务必在最后加上 "deny";否则,解析将在 "deny" 处停止,并且永远不会读取 "allow"。所以我将允许用户 AdminLogin 和 AdminBackupLogin,但拒绝任何未经身份验证或匿名的用户。
2. 创建登录表单
接下来,我们需要在根目录中创建 AdminLogin.aspx。或者说,在任何**未**受保护的目录中创建。
HTML
<table>
<tr>
<td>Admin Login ID: </td>
<td><asp:TextBox ID="Username" runat="server" Width="150" /></td>
</tr>
<tr>
<td>Admin Login Password: </td>
<td><asp:TextBox ID="Password" runat="server"
Width="150" TextMode="Password" /></td>
</tr>
<tr><td></td>
<td><asp:Button ID="btnSubmit" runat="server"
Text="Login" OnClick="btnSubmit_Click" /></td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="lblMessage" runat="server"
ForeColor="red" Text=""></asp:Label>
</td>
</tr>
</table>
代码隐藏
public void btnSubmit_Click(object sender, EventArgs e)
{
lblMessage.Text = "";
if (FormsAuthentication.Authenticate(Username.Text, Password.Text))
{
FormsAuthentication.RedirectFromLoginPage(Username.Text, false);
}
else
{
lblMessage.Text = "<b>Something went wrong...</b> please " +
"re-enter your credentials...";
}
}
3. Web.config - 将登录表单附加到表单身份验证并分配有效用户
再次编辑 Web.config,但这次,我们将附加登录表单 AdminLogin.aspx。
<configuration>...
<system.web>
...
<authentication mode="Forms">
<forms name="AdminLogin123"
loginUrl="AdminLogin.aspx"
protection="All"
path="/" >
<credentials passwordFormat="Clear">
<user name="AdminLogin" password="AdminPassword" />
<user name="AdminBackupLogin" password="AdminBackupPassword" />
</credentials>
</forms>
</authentication>
...
</system.web>
...
</configuration>
身份验证现在处于表单模式。我创建了一个 <Forms>
对象,它为 cookie 提供了唯一的名称。LoginURL
是登录表单的位置,Protection
将加密和验证 cookie,而 Path
是 cookie 的客户端存储。
下一个重要的元素是我们将用来进行身份验证的用户列表。请记住,这是一个高级示例,因此登录名和密码以明文形式存储;但是,以明文形式存储密码对于安全性来说是不合理的。有效值包括 Cear、SHA1 和 MD5。SHA1 和 MD5 都是哈希算法,可以使将密码存储在 Web.config 中更安全。
如果我想,我可以将 SQL 查询连接用于在数据库表中进行验证,而不是保留一个长的有效用户列表,甚至可以进行 LDAP 查找。对于 SQL 验证,我必须修改 AdminLogin.aspx,而不是使用 FormsAuthentication.Authenticate
来验证用户凭据,它将调用一个本地方法(即 CheckValidity
),该方法使用 SQL 查询来确定凭据是否有效。示例代码如下
Bool CheckValidity(String username, String password)
{
SqlConnection conn = new SqlConnection ("server=localhost;
database=weblogin; uid=sa; pwd=");
try
{
conn.Open();
String sqlQuery = "select count (*) from users
where username =\' " + username +
"\' and password=\' " + password + "\' ";
SqlCommand command = new SqlCommand(sqlQuery, conn);
int count = (int)command.ExecuteScalar();
return (count>0);
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
Windows 身份验证
我可以很容易地使用 Windows 身份验证。为了使用 Windows 身份验证,请确保您的网站的安全属性设置为基本、摘要身份验证或集成 Windows 身份验证。集成 Windows 身份验证是通常的设置。这将获取连接用户的凭据,并与 Windows 域进行比较,并通过返回令牌进行身份验证。所有这些都是由 IIS 完成的,因此不需要代码。
Windows 身份验证如下所示
<configuration>...
<system.web>
...
<authentication mode="Windows"/>
...
</system.web>
...
</configuration>
将目录或页面保护给特定用户将如下所示
<configuration>
...
<location path="Admin">
<system.web>
<authorization>
<allow users="domain\user1, domain\user2"/>
<deny users="?" />
</authorization>
</system.web>
</location>
...
</configuration>
结论
本文解决了保持网站开放但使用表单身份验证保护关键部分的问题。我们可以很容易地使用 Windows 身份验证来保护相同的项目。如果您希望我添加其他内容,请告诉我。