<system.web> <authentication mode="Forms"> <forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseDeviceProfile" enableCrossAppRedirects="false" /> </authentication> </system.web>
下面是对默认属性值的描述:
· | loginUrl 指向应用程序的自定义登录页。应该将登录页放在需要安全套接字层 (SSL) 的文件夹中。这有助于确保凭据从浏览器传到 Web 服务器时的完整性。 |
· | protection 设置为 All,以指定窗体身份验证票的保密性和完整性。这导致使用 machineKey 元素上指定的算法对身份验证票证进行加密,并且使用同样是 machineKey 元素上指定的哈希算法进行签名。 |
· | timeout 用于指定窗体身份验证会话的有限生存期。默认值为 30 分钟。如果颁发持久的窗体身份验证 Cookie,timeout 属性还用于设置持久 Cookie 的生存期。 |
· | name 和 path 设置为应用程序的配置文件中定义的值。 |
· | requireSSL 设置为 false。该配置意味着身份验证 Cookie 可通过未经 SSL 加密的信道进行传输。如果担心会话窃取,应考虑将 requireSSL 设置为 true。 |
· | slidingExpiration 设置为 true 以执行变化的会话生存期。这意味着只要用户在站点上处于活动状态,会话超时就会定期重置。 |
· | defaultUrl 设置为应用程序的 Default.aspx 页。 |
· | cookieless 设置为 UseDeviceProfile,以指定应用程序对所有支持 Cookie 的浏览器都使用 Cookie。如果不支持 Cookie 的浏览器访问该站点,窗体身份验证在 URL 上打包身份验证票。 |
· | enableCrossAppRedirects 设置为 false,以指明窗体身份验证不支持自动处理在应用程序之间传递的查询字符串上的票证以及作为某个窗体 POST 的一部分传递的票证。 |
授权配置 在 IIS 中,对所有使用窗体身份验证的应用程序启用异步访问。UrlAuthorizationModule 类用于帮助确保只有经过身份验证的用户才能访问页。 可以使用 authorization 元素配置 UrlAuthorizationModule,如以下示例所示。
<system.web> <authorization> <deny users="?" /> </authorization> </system.web>
使用该设置将拒绝所有未经过身份验证的用户访问应用程序中的任何页。如果未经身份验证的用户试图访问某页,窗体身份验证模块将该用户重定向到 forms 元素的 loginUrl 属性指定的登录页。 窗体身份验证控制流 图 1 显示窗体身份验证期间出现的事件顺序。 图 1. 窗体身份验证控制流
· | 用户请求应用程序的虚拟目录下的 Default.aspx 文件。因为 IIS 元数据库中启用了匿名访问,因此 IIS 允许该请求。ASP.NET 确认 authorization 元素包括 <deny users="?" /> 标记。 |
· | 服务器查找一个身份验证 Cookie。如果找不到该身份验证 Cookie,则用户重定向到配置好的登录页 (Login.aspx),该页由 forms 元素的 LoginUrl 属性。用户通过该窗体提供和提交凭据。有关起始页的信息存放在使用 RETURNURL 作为密钥的查询字符串中。服务器 HTTP 应答如下所示: 302 Found Location: http://localhost/FormsAuthTest/login.aspx?RETURNURL=%2fFormAuthTest%2fDefault.aspx |
· | 浏览器请求 Login.aspx 页,并在查询字符串中包括 RETURNURL 参数。 |
· | 服务器返回登录页以及 200 OK HTTP 状态代码。 |
· | 用户在登录页输入凭据,并将该页(包括来自查询字符串的 RETURNURL 参数)发送回服务器。 |
· | 服务器根据某个存储(如 SQL Server 数据库或 Active Directory 用户存储)验证用户凭据。登录页中的代码创建一个包含为该会话设置的窗体身份验证票的 Cookie。 在 ASP.NET 2.0 中,可以通过成员身份系统执行对用户凭据的验证。Membership 类为此提供了 ValidateUser 方法,如下所示: if (Membership.ValidateUser(userName.Text, password.Text)) { if (Request.QueryString["ReturnUrl"] != null) { FormsAuthentication.RedirectFromLoginPage(userName.Text, false); } else { FormsAuthentication.SetAuthCookie(userName.Text, false); } } else { Response.Write("Invalid UserID and Password"); }注 使用 Login Web 服务器控件时,它自动为您执行以下步骤。下文使用了前面提供的代码。 |
· | 对于经过身份验证的用户,服务器将浏览器重定向到查询字符串中的 RETURNURL 参数指定的原始 URL。服务器 HTTP 应答如下所示: 302 Found Location: http://localhost/TestSample/default.aspx |
· | 重定向之后,浏览器再次请求 Default.aspx 页。该请求包括身份验证 Cookie。 |
· | FormsAuthenticationModule 类检测窗体身份验证 Cookie 并对用户进行身份验证。身份验证成功后,FormsAuthenticationModule 类使用有关经过身份验证的用户的信息填充当前的 User 属性(由 HttpContext 对象公开)。 |
· | 由于服务器已经验证了身份验证 Cookie,因此它允许访问并返回 Default.aspx 页。 |
<httpModules> ... <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" /> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /> <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /> ... </httpModules>
每个请求只能使用一个身份验证模块。所使用的身份验证模块取决于 authentication 元素(通常位于应用程序的虚拟目录中的 Web.config 文件中)指定了哪种身份验证模式。 当 Web.config 文件中包含以下元素时,激活 FormsAuthenticationModule 类。
<authentication mode="Forms" />
FormsAuthenticationModule 类构造一个 GenericPrincipal 对象并将其存储在 HTTP 上下文中。GenericPrincipal 对象保存对一个 FormsIdentity 实例的引用,该实例代表当前经过身份验证的用户。应该允许窗体身份验证为您管理这些任务。如果应用程序有特定要求(例如,将 User 属性设置为一个实现 IPrincipal 接口的自定义类),则该应用程序应该处理 PostAuthenticate 事件。FormsAuthenticationModule 验证了窗体身份验证 Cookie 并创建了 GenericPrincipal 和 FormsIdentity 对象之后,会发生 PostAuthenticate 事件。在该代码中,可以构造一个包装 FormsIdentity 对象的自定义 IPrincipal 对象,然后将它存储在 HttpContext. User 属性中。 注 如果执行了这一操作,还需要设置 Thread.CurrentPrincipal 属性上的 IPrincipal 引用,以确保 HttpContext 对象和该线程指向相同的身份验证信息。
窗体身份验证 Cookie 调用 FormsAuthentication.SetAuthCookie 或FormsAuthentication.RedirectFromLoginPage 方法时,FormsAuthentication 类自动创建身份验证 Cookie。 典型的窗体身份验证 Cookie 中包括以下属性:
· | Name。该属性指定 Cookie 的名称。 | ||
· | Value。该属性指定 Cookie 的值。 在典型的窗体身份验证 Cookie 中,该值包含一个经过加密和签名的 FormsAuthenticationTicket 对象的字符串表示形式。该 Cookie 包含以下属性: | ||
· | Expires。该属性指定 Cookie 的到期日期和时间。仅当代码指示应该颁发一个持久的窗体身份验证 Cookie,窗体身份验证才设置该值。 | ||
· | Domain。该属性指定与 Cookie 关联的域。默认值为 null。
| ||
· | HttpOnly。该属性指定是否可以通过客户端脚本访问该 Cookie。在 ASP.NET 2.0 中,该值始终设置为 true。Internet Explorer 6 Service Pack 1 支持该 Cookie 属性,从而防止客户端脚本从 document.cookie 属性访问该 Cookie。如果尝试从客户端脚本访问该 Cookie,则返回一个空字符串。无论何时用户浏览到当前域中的 Web 站点,该 Cookie 仍然发送至服务器。 注 不支持 HttpOnly Cookie 属性的 Web 浏览器要么忽略该 Cookie,要么忽略该属性,这意味着会话仍然容易受到跨站点脚本的攻击。 | ||
· | Path。该属性指定 Cookie 的虚拟路径。默认值为"/",代表根目录。 | ||
· | Secure。该属性指出 Cookie 是否应该仅通过 HTTPS 连接传输。Secure 属性应设置为 true,以便该 Cookie 可以受 SSL 加密的保护。 | ||
· | Version。该属性指定 Cookie 的版本号。 |
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "userName", DateTime.Now, DateTime.Now.AddMinutes(30), // value of time out property false, // Value of IsPersistent property String.Empty, FormsAuthentication.FormsCookiePath);
接下来,如果 forms 元素的 protection 属性设置为 All 或 Encryption,则窗体身份验证使用 Encrypt 方法对窗体身份验证票进行加密和签名。
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
以下文本显示了当 protection 属性设置为 All 时使用的过程:
· | 创建序列化窗体身份验证票。创建票证的字节数组表示形式。 |
· | 对窗体身份验证票进行签名。字节数组的消息身份验证代码 (MAC) 的值,由使用 machineKey 元素的 validation 和 validationKey 属性指定的算法和密钥进行计算。默认情况下,使用 SHA1 算法。 |
· | 对窗体身份验证票进行加密。已经创建的第二个字节数组使用 FormsAuthentication 类的 Encrypt 方法进行加密。该 Encrypt 方法在内部使用由 machineKey 元素上的 decryption 和 decryptionKey 属性指定的算法和密钥。ASP.NET 1.1 版在默认情况下使用 3DES 算法。ASP.NET 2.0 版在默认情况下使用 Rinjdael (AES) 算法。 |
· | 根据需要创建 HTTP Cookie 或查询字符串。然后,如果窗体身份验证针对 cookieless 身份验证进行了配置,则加密的身份验证票添加到 HttpCookie 对象。使用以下代码创建该 Cookie 对象: HttpCookie authCookie = new HttpCookie( FormsAuthentication.FormsCookieName, encryptedTicket); |
· | 将窗体身份验证Cookie 设置为安全的。如果窗体身份验证票配置为使用 SSL,则 HttpCookie.Secure 属性设置为 true。这表明浏览器仅通过 HTTPS 连接发送 Cookie。 authCookie.Secure = true; |
· | 设置 HttpOnly 位。在 ASP.NET 2.0 中,始终设置该位。 |
· | 设置适当的 Cookie 属性。如果需要,设置 Cookie 的 path、domain 和 expires 属性。 |
· | 将 Cookie 添加到 Cookie 集合。将身份验证 Cookie 添加到要返回给客户端浏览器的 Cookie 集合。 Response.Cookies.Add(authCookie); |
角色授权 在 ASP.NET 2.0 中,角色授权已经得到简化。对用户进行身份验证或者将角色细节添加到身份验证 Cookie 时,不再需要检索角色信息。.NET Framework 2.0 包括一个角色管理 API,它使您能够创建和删除角色,将用户添加到角色以及从角色删除用户。该角色管理 API 将其数据存储在一个基础数据存储中,它通过针对该数据存储的适当角色提供程序访问该存储。以下角色提供程序为 .NET Framework 2.0 附带,可以与窗体身份验证一起使用:
· | SQL Server。它是默认的提供程序,将角色信息存储在 SQL Server 数据库。 |
· | 授权管理器 (AzMan)。该提供程序使用 XML 文件、Active Directory 或 Active Directory 应用程序模式 (ADAM) 中的一个 AzMan 策略存储作为其角色存储。它通常用于 Intranet 或 Extranet 方案中,其中 Windows 身份验证和 Active Directory 用于进行身份验证。 |
· | UseCookies。该值强制 FormsAuthenticationModule 类使用 Cookie 传输身份验证票。 |
· | UseUri。该值指示 FormsAuthenticationModule 类重写 URL 来传输身份验证票。 |
· | UseDeviceProfile。该值指示 FormsAuthenticationModule 类查看浏览器功能。如果浏览器支持 Cookie,则使用 Cookie;否则,重写 URL。 |
· | AutoDetect。该值通过一个动态检测机制指示 FormsAuthenticationModule 类检测浏览器是否支持 Cookie。如果检测逻辑表明不支持 Cookie,则重写 URL。 |
http://localhost/CookielessFormsAuthTest/(F(-k9DcsrIY4CAW81Rbju8KRnJ5o_gOQe0I1E_jNJLYm74izyOJK8GWdfoebgePJTEws0 _Pci7fHgTOUFTJe9jvgA2))/Test.aspx
括号中的 URL 部分包含 Cookie 通常将包含的数据。该数据在请求处理过程中由 ASP.NET 删除。该步骤由 ASP.NET ISAPI 筛选器执行,而不是在 HttpModule 类中执行。如果从一个 .aspx 页读取 Request.Path 属性,您在 URL 中不会看到任何额外的信息。如果重定向请求,URL 将自动重写。 注 难以保证 URL 中包含的身份验证票的安全。当安全性极为重要时,您应该使用 Cookie 存储身份验证票。 成员身份和登录控件 ASP.NET 2.0 引入了成员身份功能和一组登录 Web 服务器控件,它们简化了使用窗体身份验证的应用程序的实现。 成员身份为应用程序用户提供凭据存储和管理。它还提供一个成员身份 API,可以在使用窗体身份验证时简化用户凭据的验证任务。该成员身份功能构建于提供程序模型之上。该模型允许实现和配置指向不同用户存储的不同提供程序。ASP.NET 2.0 包括以下成员关系提供程序:
· | Active Directory 成员关系提供程序。该提供程序使用 Active Directory 或 Active Directory 应用程序模式 (ADAM) 用户存储。 |
· | SQL Server 成员关系提供程序。该提供程序使用 SQL Server 用户存储。 |