asp.net身份验证方式介绍

windows身份验证: IIS根据应用程序的设置执行身份验证.要使用这种验证方式,在IIS中必须禁用匿名访问.
Forms验证:用Cookie来保存用户凭证,并将 未经身份验证的用户重定向到自定义的登录页.
Passport验证:通过Microsoft的集中身份验证服务执行的,他为成员站点提供单独登录 和核心配置文件服务.

一. 配置windows身份验证
1)配置IIS设置
asp.net身份验证方式(ref:DreamSpace <wbr>of <wbr>Dern)

2)设置Web.config
<system.web>
<authentication mode = "Windows">
<!--通知操作系统将当前登录的用户的信任书传递给浏览器-->
<authorization>
<!--禁止匿名用户访问-->
<deny users = "?"/>
</authorization>
</system.web>
二.配置Forms身份认证
1)配置web.config
 
<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
WindowsMicrosoft.NetFrameworkv2.xConfig
-->
<configuration>
<appSettings/>
<connectionStrings/>
<!--允许匿名用户登录register.aspx页-->
<location path="register.aspx">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="true"/>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Forms">
<forms name="auth" loginUrl="login.aspx" timeout="30" protection="All" path="/"></forms>
</authentication>
<!--禁止匿名用户登录-->
<authorization>
<deny users="?"/>
</authorization>
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
</system.web>
</configuration>

2)登录页面代码
login.aspx
[/code]
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="登陆" /></div>
</form>
</body>
</html>
 

[code]
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
FormsAuthentication.RedirectFromLoginPage(this.TextBox1.Text, false);
}
}

三.配置Passport身份认证
需要安装Passport Software Developer Kit.这种认证方式适合于跨站之间的应用,用户只有一个用户名和密码可以访问任何成员站。

IIS 身份验证

如果 ASP.NET 针对 Windows 身份验证进行配置,则 ASP.NET 依靠 IIS,利用配置好的身份验证模式对其客户端进行身份验证。IIS 通过检查特定应用程序的元数据库设置来确定其身份验证模式。成功验证某个用户的身份后,IIS 将代表经过身份验证的用户的 Windows 令牌传递给宿主 ASP.NET 的 ASP.NET 辅助进程 (w3wp.exe)。如果应用程序使用在 IIS 中配置的虚拟目录来支持匿名访问,该令牌代表匿名 Internet 用户帐户;否则,该令牌代表经过身份验证的用户。

IIS 支持以下身份验证模式:

匿名。如果不需要对客户端进行身份验证(或者使用自定义身份验证机制,如窗体身份验证),则可将 IIS 配置为允许匿名访问。在该事件中,IIS 创建一个 Windows 令牌来表示具有相同匿名(或客人)帐户的所有匿名用户。默认的匿名帐户是 IUSR_MACHINENAME,其中 MACHINENAME 是安装期间指定的计算机的 NetBIOS 名称。

基本。基本身份验证要求用户以用户名和密码的形式提供凭据来证明他们的身份。基本身份验证基于 Internet 标准 RFC 2617,所有常用浏览器都支持它。用户的凭据以未加密的 Base64 编码格式从浏览器传送到 Web 服务器。为了更好保护这些凭据,只要在使用基本身份验证同时再使用安全套接字层 (SSL) 即可。由于 Web 服务器包含未加密的用户凭据,因此 ASP.NET 应用程序可以模拟调用方并使用他们的凭据来访问网络资源。

集成的 Windows。集成的 Windows 身份验证(以前称为 NTLM,也称为 Windows NT 质询/应答身份验证,Windows NT Challenge/Response)是使用 Kerberos v5 身份验证还是 NTLM 身份验证,取决于客户端和服务器的配置。服务器与客户端协商确定要使用的协议。如果满足以下条件,则使用 Kerberos 身份验证:

ASP.NET Web 应用程序正在 NetworkService 帐户或自定义域帐户下运行。如果应用程序在本地帐户(如 Windows 2000 Server 上的 ASPNET 帐户)上运行,则使用 NTLM 身份验证。

域帐户的 Active Directory 中有一个服务主要名称 (SPN),该域帐户用于运行客户端进行身份验证所使用的服务。

客户端计算机和服务器计算机至少需要运行 Windows 2000 Server,且处在相同的(即信任的)Windows 域中。

默认情况下,对于 Windows Server 2003 操作系统启用集成 Windows 身份验证。然而,如果 Windows Server 2003 Service Pack 1 (SP1) 作为 Windows Server 2003 操作系统整合安装的一部分进行安装,则默认情况下禁用集成 Windows 身份验证。如果使用 SP1 升级 Windows Server 2003,则集成 Windows 身份验证的设置与其 Windows Server 2003 设置相同。

应该使用集成 Windows 身份验证而不是基本身份验证,因为前者避免了通过网络传输用户凭据。由于 Kerberos v5 身份验证支持相互身份验证,因此用户还可以对正在连接的服务器进行身份验证。

集成 Windows 身份验证最适合于 Intranet 环境,其中的客户端计算机和 Web 服务器计算机都是相同(即信任的)域的一部分。

NTLM 身份验证

NTLM 是用于 Windows NT 和 Windows 2000 Server 工作组环境的身份验证协议。它还用在必须对 Windows NT 系统进行身份验证的混合 Windows 2000 Active Directory 域环境中。当 Windows 2000 Server 转换为不存在下层 Windows NT 域控制器的本机模式时,禁用 NTLM。然后 Kerberos v5 变成企业级的默认身份验证协议。

NTLM 身份验证机制

图 1 显示 NTLM 协议。

1. NTLM 质询 / 应答机制

下面概述质询/应答机制:

用户请求访问。用户尝试通过提供用户凭据登录到客户端。登录前,客户端计算机缓存密码的哈希值并放弃密码。客户端向服务器发送一个请 求,该请求包括用户名以及纯文本格式的请求。

服务器发送质询消息。服务器生成一个称为质询的 16 字节随机数(即 NONCE),并将它发送到客户端。

客户端发送应答消息。客户端使用由用户的密码生成的一个密码哈希值来加密服务器发送的质询。它以应答的形式将这个加密的质询发回到服 务器。

服务器将质询和应答发送到域控制器。服务器将用户名、原始质询以及应答从客户端计算机发送到域控制器。

域控制器比较质询和应答以对用户进行身份验证。域控制器获取该用户的密码哈希值,然后使用该哈希值对原始质询进行加密。接下来,域控 制器将加密的质询与客户端计算机的应答进行比较。如果匹配,域控制器则发送该用户已经过身份验证的服务器确认。

服务器向客户端发送应答。假定凭据有效,服务器授予对所请求的服务或资源的客户端访问权。

Kerberos 身份验证

与 NTLM 身份验证相比,Kerberos 身份验证具有以下优势:

相互身份验证。当客户端使用 Kerberos v5 协议对特定服务器上的特定服务进行身份验证,Kerberos 为客户端提供网络上恶意代码不会模拟该服务的保证。

委托支持。使用 Kerberos 身份验证对客户端进行身份验证的服务器可以模拟这些客户端,并使用该客户端的安全上下文访问网络资源。

性能。Kerberos 身份验证提供优于 NTLM 身份验证的改进的性能。

简化的信任管理。具有多个域的网络不再需要一组复杂的显式、点对点信任关系。

互操作性。Microsoft 实现的 Kerberos 协议基于向 Internet 工程任务组 (IETF) 推荐的标准跟踪规范。因此,Windows 2000 中协议的实现为与其他网络的互操作奠定了基础(其中 Kerberos 版本 5 用于身份验证)。

Kerberos 身份验证机制

图 2 显示 Kerberos 身份验证协议的简化视图。

2. Kerberos 身份验证

当客户端对网络服务进行身份验证之后,Kerberos v5 协议遵循以下步骤:

客户端从 KDC 请求 TGT。用户试图通过提供用户凭据登录到客户端。客户端计算机 上的 Kerberos 服务向密钥发行中心 (KDC) 发送一个 Kerberos 身份验证服务请求。该请求包含用户名、请求票证授予票证(ticket-granting ticket,TGT)所获取的服务信息,以及使用用户的长期密钥(即密码)加密的时间戳。

在 Windows 2000 Server 或 Windows Server 2003 操作系统上,域控制器充当 KDC,而 Active Directory 宿主安全帐户数据库。

身份验证服务发送加密的 TGT 和会话密钥。KDC 为来自 Active Directory 的用户获取长期密钥(即密码),然后解密随请求一起传送的时间戳。如果该时间戳有效,则用户是真正的用户。KDC 身份验证服务创建一个登录会话密钥,并使用用户的长期密钥对该副本进行加密。然后,该身份验证服务创建一个 TGT,它包括用户信息和登录会话密钥。最后,该身份验证服务使用自己的密钥加密 TGT,并将加密的会话密钥和加密的 TGT 传递给客户端。

客户端从 TGT 请求服务器访问。客户端使用其长期密钥(即密码)解密登录会话密钥,并在本地缓存 它。此外,客户端还将加密的 TGT 存储在它的缓存中。访问网络服务时,客户端向 KDC 票证授予服务(ticket-granting service,TGS)发送一个包含信息的请求,这些信息包括用户名、使用用户登录会话密钥加密的验证者消息、TGT,以及用户想访问的服务(和服务 器)名称。

TGS 发送加密的会话密钥和票证。KDC 上的 TGS 使用自己的密钥解密 KDC 并提取登录会话密钥。它使用该登录会话密钥解密验证者消息(通常是时间戳)。如果验证者消息成功解密,TGS 从 TGT 提取用户信息,并使用用户信息创建一个用于访问该服务的服务会话密钥。它使用该用户的登录会话密钥对该服务会话密钥的一个副本进行加密,创建一个具有服务 会话密钥和用户信息的服务票证,然后使用该服务的长期密钥(密码)对该服务票证进行加密。然后,TGS 将加密的服务会话密钥和服务票证添加到客户端。

客户端发送服务票证。客户端访问服务时,向服务器发送一个请求。该请求包含验证者消息(时间戳),该消息使用服务会话密钥和服务票证 进行加密。

服务器发送加密的时间戳以进行客户端验证。服务器解密服务票证并提取服务会话密钥。通过使用服务会话密钥,服务器解密验证者消息(时 间戳)并计算它。如果验证者通过测试,则服务器使用服务会话密钥对验证者(时间戳)进行加密,然后将验证者传回到客户端。客户端解密时间戳,如果该时间戳 与原始时间戳相同,则该服务是真正的,客户端继续连接。

服务的主要名称

Kerberos v5 身份验证协议之所以使用服务的主要名称 (SPN),原因如下:

支持相互身份验证。

允许一个客户端请求票证,进而允许该客户端与特定服务通讯。

例如,如果某个客户端需要获得一个票证,并对在侦听端口 4766 运行的计算机 (MyServer) 上的特定服务 (MyService) 进行身份验证,则该客户端使用根据该信息构造的名称从 KDC 请求一个票证,如下所示:

MyService/MyServer:4766

在 Active Directory 中注册的 SPN 在该名称和运行所请求的服务的域帐户之间维护一个映射。通过使用该机制,恶意用户难以在网络上模拟服务。恶意用户必须禁用实际服务并从该网络移除实际服务 器。然后,恶意用户必须向网络中添加一台同名的新计算机并公开重复的服务。由于客户端使用具有相互身份验证的 Kerberos v5 协议,因此该客户端将无法使用重复的服务,除非它可以提供配置实际服务进行运行的域帐户的密码。

Kerberos 身份验证

与 NTLM 身份验证相比,Kerberos 身份验证具有以下优势:

相互身份验证。当客户端使用 Kerberos v5 协议对特定服务器上的特定服务进行身份验证,Kerberos 为客户端提供网络上恶意代码不会模拟该服务的保证。

委托支持。使用 Kerberos 身份验证对客户端进行身份验证的服务器可以模拟这些客户端,并使用该客户端的安全上下文访问网络资源。

性能。Kerberos 身份验证提供优于 NTLM 身份验证的改进的性能。

简化的信任管理。具有多个域的网络不再需要一组复杂的显式、点对点信任关系。

互操作性。Microsoft 实现的 Kerberos 协议基于向 Internet 工程任务组 (IETF) 推荐的标准跟踪规范。因此,Windows 2000 中协议的实现为与其他网络的互操作奠定了基础(其中 Kerberos 版本 5 用于身份验证)。

Kerberos 身份验证机制

图 2 显示 Kerberos 身份验证协议的简化视图。

2. Kerberos 身份验证

当客户端对网络服务进行身份验证之后,Kerberos v5 协议遵循以下步骤:

客户端从 KDC 请求 TGT。用户试图通过提供用户凭据登录到客户端。客户端计算机 上的 Kerberos 服务向密钥发行中心 (KDC) 发送一个 Kerberos 身份验证服务请求。该请求包含用户名、请求票证授予票证(ticket-granting ticket,TGT)所获取的服务信息,以及使用用户的长期密钥(即密码)加密的时间戳。

在 Windows 2000 Server 或 Windows Server 2003 操作系统上,域控制器充当 KDC,而 Active Directory 宿主安全帐户数据库。

身份验证服务发送加密的 TGT 和会话密钥。KDC 为来自 Active Directory 的用户获取长期密钥(即密码),然后解密随请求一起传送的时间戳。如果该时间戳有效,则用户是真正的用户。KDC 身份验证服务创建一个登录会话密钥,并使用用户的长期密钥对该副本进行加密。然后,该身份验证服务创建一个 TGT,它包括用户信息和登录会话密钥。最后,该身份验证服务使用自己的密钥加密 TGT,并将加密的会话密钥和加密的 TGT 传递给客户端。

客户端从 TGT 请求服务器访问。客户端使用其长期密钥(即密码)解密登录会话密钥,并在本地缓存 它。此外,客户端还将加密的 TGT 存储在它的缓存中。访问网络服务时,客户端向 KDC 票证授予服务(ticket-granting service,TGS)发送一个包含信息的请求,这些信息包括用户名、使用用户登录会话密钥加密的验证者消息、TGT,以及用户想访问的服务(和服务 器)名称。

TGS 发送加密的会话密钥和票证。KDC 上的 TGS 使用自己的密钥解密 KDC 并提取登录会话密钥。它使用该登录会话密钥解密验证者消息(通常是时间戳)。如果验证者消息成功解密,TGS 从 TGT 提取用户信息,并使用用户信息创建一个用于访问该服务的服务会话密钥。它使用该用户的登录会话密钥对该服务会话密钥的一个副本进行加密,创建一个具有服务 会话密钥和用户信息的服务票证,然后使用该服务的长期密钥(密码)对该服务票证进行加密。然后,TGS 将加密的服务会话密钥和服务票证添加到客户端。

客户端发送服务票证。客户端访问服务时,向服务器发送一个请求。该请求包含验证者消息(时间戳),该消息使用服务会话密钥和服务票证 进行加密。

服务器发送加密的时间戳以进行客户端验证。服务器解密服务票证并提取服务会话密钥。通过使用服务会话密钥,服务器解密验证者消息(时 间戳)并计算它。如果验证者通过测试,则服务器使用服务会话密钥对验证者(时间戳)进行加密,然后将验证者传回到客户端。客户端解密时间戳,如果该时间戳 与原始时间戳相同,则该服务是真正的,客户端继续连接。

服务的主要名称

Kerberos v5 身份验证协议之所以使用服务的主要名称 (SPN),原因如下:

支持相互身份验证。

允许一个客户端请求票证,进而允许该客户端与特定服务通讯。

例如,如果某个客户端需要获得一个票证,并对在侦听端口 4766 运行的计算机 (MyServer) 上的特定服务 (MyService) 进行身份验证,则该客户端使用根据该信息构造的名称从 KDC 请求一个票证,如下所示:

MyService/MyServer:4766

在 Active Directory 中注册的 SPN 在该名称和运行所请求的服务的域帐户之间维护一个映射。通过使用该机制,恶意用户难以在网络上模拟服务。恶意用户必须禁用实际服务并从该网络移除实际服务 器。然后,恶意用户必须向网络中添加一台同名的新计算机并公开重复的服务。由于客户端使用具有相互身份验证的 Kerberos v5 协议,因此该客户端将无法使用重复的服务,除非它可以提供配置实际服务进行运行的域帐户的密码。

ASP.NET 身份验证

IIS 向 ASP.NET 传递代表经过身份验证的用户或匿名用户帐户的令牌。该令牌在一个包含在 IPrincipal 对象中的 IIdentity 对象中维护,IPrincipal 对象进而附加到当前 Web 请求线程。可以通过 HttpContext.User 属性访问 IPrincipalIIdentity 对象。这些对象和该属性由身份验证模块设置,这些模块作为 HTTP 模块实现并作为 ASP.NET 管道的一个标准部分进行调用,如图 3 所示。

3. ASP.NET 管道

ASP.NET 管道模型包含一个 HttpApplication 对象、多个 HTTP 模块对象,以及一个 HTTP 处理程序对象及其相关的工厂对象。HttpRuntime 对象用于处理序列的开头。在整个请求生命周期中,HttpContext 对象用于传递有关请求和响应的详细信息。

有关 ASP.NET 请求生命周期的详细信息,请参阅"ASP.NET Life Cycle",网址是 http://msdn2.microsoft.com/library/ms227435(en-US,VS.80).aspx。

身份验证模块

ASP.NET 2.0 在计算机级别的 Web.config 文件中定义一组 HTTP 模块。其中包括大量身份验证模块,如下所示:

<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 元素中指定了哪种身份验证模式。该身份验证模块创建一个 IPrincipal 对象并将它存储在 HttpContext.User 属性中。这是很关键的,因为其他授权模块使用该 IPrincipal 对象作出授权决定。

当 IIS 中启用匿名访问且 authentication 元素的 mode 属性设置为 none 时,有一个特殊模块将默认的匿名原则添加到 HttpContext.User 属性中。因此,在进行身份验证之后,HttpContext.User 绝不是一个空引用(在 Visual Basic 中为 Nothing)。

WindowsAuthenticationModule

如果 Web.config 文件包含以下元素,则激活 WindowsAuthenticationModule 类。

<authentication mode="Windows" />

WindowsAuthenticationModule 类负责创建 WindowsPrincipalWindowsIdentity 对象来表示经过身份验证的用户,并且负责将这些对象附加到当前 Web 请求。

对于 Windows 身份验证,遵循以下步骤:

  • WindowsAuthenticationModule 使用从 IIS 传递到 ASP.NET 的 Windows 访问令牌创建一个 WindowsPrincipal 对象。该令牌包装在 HttpContext 类的 WorkerRequest 属性中。引发 AuthenticateRequest 事件时,WindowsAuthenticationModuleHttpContext 类检索该令牌并创建 WindowsPrincipal 对象。HttpContext.User 用该 WindowsPrincipal 对象进行设置,它表示所有经过身份验证的模块和 ASP.NET 页的经过身份验证的用户的安全上下文。

  • WindowsAuthenticationModule 类使用 P/Invoke 调用 Win32 函数并获得该用户所属的 Windows 组的列表。这些组用于填充 WindowsPrincipal 角色列表。

  • WindowsAuthenticationModule 类将 WindowsPrincipal 对象存储在 HttpContext.User 属性中。随后,授权模块用它对经过身份验证的用户授权。

    注: DefaultAuthenticationModule 类(也是 ASP.NET 管道的一部分)将 Thread.CurrentPrincipal 属性设置为与 HttpContext.User 属性相同的值。它在处理 AuthenticateRequest 事件之后进行此操作。

授权模块

WindowsAuthenticationModule 类完成其处理之后,如果未拒绝请求,则调用授权模块。授权模块也在计算机级别的 Web.config 文件中的 httpModules 元素中定义,如下所示:

<httpModules> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" /> <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" /> <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" /> </httpModules>

UrlAuthorizationModule

调用 UrlAuthorizationModule 类时,它在计算机级别或应用程序特定的 Web.config 文件中查找 authorization 元素。如果存在该元素,则 UrlAuthorizationModule 类从 HttpContext.User 属性检索 IPrincipal 对象,然后使用指定的动词(GET、POST 等)来确定是否授权该用户访问请求的资源。

FileAuthorizationModule

接下来,调用 FileAuthorizationModule 类。它检查 HttpContext.User.Identity 属性中的 IIdentity 对象是否是 WindowsIdentity 类的一个实例。如果 IIdentity 对象不是 WindowsIdentity 类的一个实例,则 FileAuthorizationModule 类停止处理。

如果存在 WindowsIdentity 类的一个实例,则 FileAuthorizationModule 类调用 AccessCheck Win32 函数(通过 P/Invoke)来确定是否授权经过身份验证的客户端访问请求的文件。如果该文件的安全描述符的随机访问控制列表 (DACL) 中至少包含一个 Read 访问控制项 (ACE),则允许该请求继续。否则,FileAuthorizationModule 类调用 HttpApplication.CompleteRequest 方法并将状态码 401 返回到客户端。

安全上下文

.NET Framework 使用以下两个接口封装 Windows 令牌和登录会话:

  • System.Security.Principal.IPrincipal

  • System.Security.Principal.IIdentity(它公开为 IPrincipal 接口中的一个属性。)

HttpContext.User

在 ASP.NET 中,用 WindowsPrincipalWindowsIdentity 类表示使用 Windows 身份验证进行身份验证的用户的安全上下文。使用 Windows 身份验证的 ASP.NET 应用程序可以通过 HttpContext.User 属性访问 WindowsPrincipal 类。

要检索启动当前请求的 Windows 经过身份验证的用户的安全上下文,使用以下代码:

using System.Security.Principal; ... // Obtain the authenticated user's Identity WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;

WindowsIdentity.GetCurrent

WindowsIdentity.GetCurrent 方法可用于获得当前运行的 Win32 线程的安全上下文的标识。如果不使用模拟,线程继承 IIS 6.0(默认情况下的 NetworkService 帐户)上进程的安全上下文。

该安全上下文在访问本地资源时使用。通过使用经过身份验证的初始用户的安全上下文或使用固定标识,您可以使用模拟重写该安全上下文。

要检索运行应用程序的安全上下文,使用以下代码:

using System.Security.Principal; ... // Obtain the authenticated user's identity. WindowsIdentity winId = WindowsIdentity.GetCurrent(); WindowsPrincipal winPrincipal = new WindowsPrincipal(winId);

Thread.CurrentPrincipal

ASP.NET 应用程序中的每个线程公开一个 CurrentPrincipal 对象,该对象保存经过身份验证的初始用户的安全上下文。该安全上下文可用于基于角色的授权。

要检索线程的当前原则,使用以下代码:

using System.Security.Principal; ... // Obtain the authenticated user's identity WindowsPrincipal winPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal();

表 1 显示从各种标识属性获得的结果标识,当您的应用程序使用 Windows 身份验证且 IIS 配置为使用集成 Windows 身份验证时,可以从 ASP.NET 应用程序使用这些标识属性。

 

表 1:线程公开的 CurrentPrincipal Object

Web.config 设置

变量位置

结果标识

<identity impersonate="true"/>
<authentication mode="Windows" />

HttpContext
WindowsIdentity
线程

DomainUserName
DomainUserName
DomainUserName

<identity impersonate="false"/>
<authentication mode="Windows" />

HttpContext
WindowsIdentity
线程

DomainUserName
NT AUTHORITYNETWORK SERVICE
DomainUserName

<identity impersonate="true"/>
<authentication mode="Forms" />

HttpContext
WindowsIdentity
线程

用户提供的名称
DomainUserName
用户提供的名称

<identity impersonate="false"/>
<authentication mode="Forms" />

HttpContext
WindowsIdentity
线程

用户提供的名称
NT AUTHORITYNETWORK SERVICE
用户提供的名称

 

返 回页首

模拟

ASP.NET 应用程序可以使用模拟来执行操作,使用经过身份验证的客户端或特定 Windows 帐户的安全上下文来访问资源。

初始用户模拟

要模拟初始(经过身份验证的)用户,请在 Web.config 文件中使用以下配置:

<authentication mode="Windows" /> <identity impersonate="true" />

使用该配置,ASP.NET 始终模拟经过身份验证的用户,且所有资源访问均使用经过身份验证的用户的安全上下文执行。如果您的应用程序的虚拟目录上启用了匿名访问,则模拟 IUSR_MACHINENAME 帐户。

要暂时模拟经过身份验证的调用方,将 identity 元素的 impersonate 属性设置为 false, 然后使用以下代码:

using System.Security.Principal; ... // Obtain the authenticated user's identity. WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity; WindowsImpersonationContext ctx = null; try { // Start impersonating. ctx = winId.Impersonate(); // Now impersonating. // Access resources using the identity of the authenticated user. } // Prevent exceptions from propagating. catch { } finally { // Revert impersonation. if (ctx != null) ctx.Undo(); } // Back to running under the default ASP.NET process identity.

这段代码模拟经过身份验证的初始用户。在 HttpContext.Current.User.Identity 对象中维护初始用户的标识和 Windows 令牌。

固定标识模拟

如果需要在应用程序的整个生命周期中模拟相同的标识,可以在 Web.config 文件中的 identity 元素上指定凭据。以下示例显示如何模拟名为"TestUser"的 Windows 帐户。

如果使用该方法,应该对这些凭据进行加密。使用 ASP.NET 2.0,您可以使用 ASP.NET IIS 注册工具 (Aspnet_regiis.exe)。使用 ASP.NET 1.1 版,您可以使用 Aspnet_setreg.exe 实用工具。有关该实用工具的详细信息,请参阅 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrfaspnetiisregistrationtoolaspnet_regiisexe.asp。

要在 ASP.NET 应用程序中使用固定标识进行资源访问,可使用 Windows 2000 Server 或 Windows Server 2003 上的 identity 元素来配置凭据。如果正在运行 Windows Server 2003,其中的 IIS 6.0 配置为运行在辅助进程隔离模式下(默认情况),则可通过将 ASP.NET 应用程序配置为在自定义应用程序池(在特定的域标识下运行)中运行来避免模拟。然后,可以使用指定的域标识访问资源而无需使用模拟。

返 回页首

委托

模拟只提供对本地资源的访问。委托是一个扩展的模拟功能,它允许您使用模拟令牌访问网络资源。

如果应用程序使用 Kerberos v5 身份验证对其用户进行身份验证,则可使用 Kerberos 委托在应用程序的各层传递用户标识并访问网络资源。如果应用程序不使用 Kerberos v5 身份验证,则可使用协议转换切换到 Kerberos,然后使用委托传递该标识。

Windows Server 2003 中的约束委托需要 Kerberos 身份验证。如果您的应用程序无法使用 Kerberos 身份验证对其调用方进行身份验证,您可以使用协议转换从可选的非 Windows 身份验证模式(如,窗体或证书身份验证)切换到 Kerberos 身份验证。然后,可使用具有约束委托的 Kerberos 访问下游网络资源。

约束的和未约束的委托

Windows 2000 Server 上的 Kerberos 委托是未约束的。Active Directory 中配置了委托的服务器可在使用模拟的用户安全上下文的同时访问任何网络资源或网络上的任何计算机。这会带来潜在的安全威胁,尤其是 Web 服务器遭受恶意用户攻击时。

为了解决该安全问题,Windows Server 2003 引入了约束的委托。这使管理员能够在使用模拟的用户安全上下文时准确 指定另一个服务器或域帐户可以访问的服务。

配置委托

要使用 Kerberos 委托,需要适当的 Active Directory 配置。

要授予 Web 服务器委托客户端凭据的权限,请按以下方式配置 Active Directory:

  • 如果在 NetworkService 帐户下运行应用程序,Web 服务器计算机帐户必须在 Active Directory 中标记为受信任委托。

  • 如果在自定义域帐户下运行应用程序,该用户帐户必须在 Active Directory 中标记为受信任委托。

  • 如果应用程序模拟一个用户帐户,请确保应用程序模拟的用户帐户在 Active Directory 中未标记为"敏感帐户,不能被委托"。

有关协议转换和约束委托的详细信息,请参阅 How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0。