接下来,我们在配置文件web.config中建立我们的定制MembershipProvider:
<providers>
<clear/>
<add name="BlogoMembershipProvider" applicationName="BLOGO.NET"
type="BLOGO.NET.Utils.BlogoMembershipProvider" />
</providers>
</membership>
上面的配置要求应用程序使用我们的定制的MembershipProvider组件—BlogoMembershipProvider。
最后,我们需要在配置文件web.config中建立一些授权规则。对于本系统而言,这一点非常简单:除了位于“View/Pages/Admin”文件夹中的页面,所有其他的页面都可以不经认证而进行访问。相关配置代码如下:
<location path="View/Pages/Admin">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
在设置完web.config文件后,现在来进一步讨论我们的定制MembershipProvider,它位于文件Code/Utils/BlogoMembershipProvider.cs中。
这个定制MembershipProvider的目的是鉴别进入到本博客系统中的用户。为此,我们可以从ASP.NET的MembershipProvider基类派生我们自己的定制成员身份类。有许多种方法可以重载基类,但是我们将仅重载一个方法—ValidateUser。
下面给出重载基类MembershipProvider的方法ValidateUser的相关代码:
{
bool result = false;
try
{
if (AuthorManager.Count(0, 10) < 1 && username == "admin"
&& password == "admin")
{
result = true;
}
else
{
string salt = null;
string hashedPassword = null;
Author currentUser = AuthorManager.GetItem(username);
if (currentUser != null)
{
salt = currentUser.salt;
hashedPassword = Hash.HashPassword(password, salt);
if (hashedPassword.Equals(currentUser.password))
{
//认证成功
result = true;
}
}
}
}
catch (Exception)
{
}
return result;
}
上面重载方法代码的总体实现逻辑是:
·使用业务层的AuthorManager类计算出已定义的用户。如果不存在任何用户,则说明系统配置不当,因此允许使用默认的用户名和口令“admin”。如果至少定义了一个用户,则不接受“admin”,并且说明系统安全运行。
·根据提供的用户名从业务层中查找相应的Author对象。如果找到,则把当前提供的口令与存储在数据库中的经盐化的口令进行比较。如果口令匹配,则认证成功。
·如果不存在这样的用户,或如果数据库中的哈希值不相匹配,则认证失败.
在修改了配置文件web.config并创建了定制的MembershipProvider后,开发登录表单就很容易了。此表单位于View/Pages/Login.aspx路径下,其中仅包含下面的标记代码:
Inherits="BLOGO.NET.View.Pages.Login"
MasterPageFile="~/View/Masters/Site.Master" %>
<asp:content id="ContentPlaceHolder" contentplaceholderid="ContentPlaceHolderPrimary"
runat="server">
<form id="form" runat="server">
<div class="post">
<h3>访问管理面板登录</h3>
<asp:Login ID="LoginBlogo" runat="server"
MembershipProvider="BlogoMembershipProvider"
DisplayRememberMe="False"
RememberMeSet="False"
FailureText="无效的凭证。请重新输入!">
<LoginButtonStyle CssClass="button" />
</asp:Login>
<asp:Label ID="LabelMessage" runat="server" Text=""></asp:Label>
</div>
</form>
</asp:content>
此外,还请注意以下几点:
·该登录表单直接继承自站点母版页面。
·在这个页面上,使用了一个登录控件。它被配置使用我们的定制MembershipProvider。我们还配置了相应的错误文本以防发生认证失败.
·我们在登录表单的底部包括了一个标签控件。这个标签用于显示指令以防不存在用户定义。我们在表单的Page_Load事件处理器函数中填充这个标签中的文本。
经过上面简单的编程,现在我们实现一个强有力的定制的安全模型。所有这些主要得益于重用大量的ASP.NET标准设施:
·当用户访问任何访问者页面时,不出现登录表单。
·当用户访问任何管理页面时,他们首先被导航到登录页面(如果他们已经认证—这可以通过浏览器端的Cookie进行探测,并且跳过登录页面)。
·在该登录表单中,使用定制的Membership提供者检查凭证。
·一旦失败,便显示认证错误文本。
·一旦成功,该用户即被认证并且被重定向到最初想进入的页面。