基于表单的身份验证实现

在Web应用开发中,身份验证是一个重要的环节,它确保了只有授权用户才能访问敏感资源。本文将介绍如何使用表单验证来控制对特定文件夹的访问权限,特别是如何仅允许具有管理员角色的用户访问特定资源。

在开发网站时,经常需要对不同用户设置不同的访问权限。例如,普通用户只能浏览网站,而注册用户可以执行一些操作,如添加或删除内容。对于具有管理员角色的用户,希望他们能够访问更多的资源,如管理文件夹。本文将探讨如何实现这种基于角色的访问控制。

使用代码

首先,需要下载并解压示例代码,然后在IIS中为其创建一个虚拟目录。根目录包含登录页面(login.aspx)、登出页面(logout.aspx)、首页(default.aspx)以及一个名为“admin”的文件夹。在“admin”文件夹中,放置了一个名为default.aspx的文件,这是希望阻止普通用户访问的文件。

在web.config文件中,需要设置身份验证模式为“Forms”,并定义一个特定于“Admin”文件夹的授权规则,如下所示:

<location path="Admin"> <system.web> <authorization> <allow roles="Administrators" /> <deny users="*" /> </authorization> </system.web> </location> <authentication mode="Forms"> <forms name="AuthCookie" path="/" loginUrl="login.aspx" protection="All" timeout="30"> </forms> </authentication>

请确保将<allow roles="Administrators" />放在<deny users="*" />之前,否则没有人能够访问“admin”文件夹。

为了使网站更易于维护,使用web.sitemap文件来定义网站结构。在web.sitemap文件中,创建了几个SiteMapNode,并将“Administrators”角色分配给相应的节点,如下所示:

<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"> <siteMapNode url="~" title="Home" description=""> <siteMapNode url="default.aspx" title="Home" description="" roles="*" /> <siteMapNode url="login.aspx" title="Login" description="" roles="*" /> <siteMapNode url="Admin/" title="Administration" description=""> <siteMapNode url="Admin/default.aspx" title="Administration" description="" roles="Administrators" /> </siteMapNode> <siteMapNode url="logout.aspx" title="Logout" description="" roles="*" /> </siteMapNode> </siteMap>

当用户首次访问网站时,他们可以看到“Administration”超链接。点击该链接后,由于web.config文件的设置,IIS的FormsAuthentication对象会将用户重定向到login.aspx页面,要求用户登录。用户输入用户名和密码后,通过数据库访问等多种方法进行验证。验证成功后,为特定用户分配“Administrators”角色,如下所示:

FormsAuthenticationUtil.RedirectFromLoginPage("Lewis", "Administrators", true);

FormsAuthenticationUtil是一个第三方DLL,它为用户创建一个身份验证票据,并将用户的登录状态更改为“已登录”。后来,停止使用这个DLL,因为需要完全控制用户的登录过程。

创建了一个用户类,专门处理用户的登录和注册过程等。以下是代码片段:

public static void CreateTicket(ENetUser newUser, bool persistantCookie) { string roles = "users"; if (newUser.Email.ToLower().Trim() == "abc@hotmail.com" || newUser.Email.ToLower().Trim() == "john.dole@pertronic.co.nz") roles = "Administrators"; roles += "," + newUser.ID; roles += "," + newUser.ID; // 创建一个新的票据用于身份验证 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, newUser.UserName, DateTime.Now, DateTime.Now.AddMinutes(30), persistantCookie, roles, FormsAuthentication.FormsCookiePath); // 加密cookie以安全传输 string hash = FormsAuthentication.Encrypt(ticket); HttpCookie cookie = new HttpCookie( FormsAuthentication.FormsCookieName, hash); if (ticket.IsPersistent) cookie.Expires = ticket.Expiration; System.Web.HttpContext.Current.Response.Cookies.Add(cookie); }

如上所示,为用户创建了一个票据,并在用户的PC上添加了一个cookie。当用户下次访问网站时,从该Cookie重新创建用户的票据。

需要告诉Web应用程序如何验证用户。在global.asax文件中添加了以下代码行,如果Web根目录中没有该文件,请通过选择Visual Studio 2008的“添加新项”从“Web站点”菜单中添加它。

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { if (HttpContext.Current.User != null) { if (HttpContext.Current.User.Identity.IsAuthenticated) { if (HttpContext.Current.User.Identity is FormsIdentity) { FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; FormsAuthenticationTicket ticket = id.Ticket; string userData = ticket.UserData; string[] roles = userData.Split(','); HttpContext.Current.User = new GenericPrincipal(id, roles); } } } }

如上所示,一旦用户登录,他们将被认证,但他们还没有“Administrators”角色。使用上述例程为用户分配该角色。

在网站上,在global.asax文件中添加了以下代码,在会话开始时读取cookie,为用户提供票据,应用程序认证方法将使用该票据授予用户“administrators”角色。

void Session_Start(object sender, EventArgs e) { HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie != null) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485