- Remoting 接收
- 对驻留在 ASP.NET 中的请求进行剖析
- ASP.NET 和 HTTP 通道
- 驻留在 ASP.NET 中
- 驻留在 Windows 服务中
- 自定义身份验证
- 更多信息
- 使用文件授权
- 更多信息
- 更多信息
- 指定客户端凭证
- 使用 DefaultCredentials
- 显式配置
- 编程配置
- 使用特定凭证
- 请求特定的验证类型Request a Specific Authentication Type
- 设置 preauthenticate 属性
- 使用 connectiongroupname 属性
- 带有 Kerberos 委派的默认凭据
- 带有基本身份验证或表单身份验证的显式凭证
- 基本身份验证
- 表单身份验证
Microsoft Corporation
本章内容
.NET Framework 提供一种远程基础结构,它允许客户端与远程应用程序域和进程或远程计算机所承载的对象进行通信。在分布式 Web 应用程序中,通常使用 .NET Remoting 作为当前层组件访问位于中间层业务逻辑组件的一种机制。
本章描述了如何在使用 .NET Remoting 的分布式 Web 应用程序中实现身份验证、授权以及安全通信。
目标
使用本章来:
• |
保护 .NET Remoting 解决方案的安全 |
• |
建立安全的远程组件 |
• |
了解使用 .NET Remoting 的分布式应用程序的体系结构和操作,并且熟悉 .NET Remoting 的扩展能力。 |
• |
选择合适的托管进程。 |
• |
识别和使用 .NET Remoting 提供的网关守卫。 |
• |
调用远程对象来传递客户端凭证 |
• |
将调用者标识从远程组件传递到下游系统。 |
• |
知道何时使用 .NET Remoting 以及何时使用 Web 服务作为分布式 Web 应用程序中的一部分。 |
• |
为.NET Remoting 解决方案设计合适的身份验证、授权和的安全通信机制。 |
适用于:
本章适用于下列产品和技术:
• |
Microsoft® Windows® Server 2000 和 Windows Server™ 2003 操作系统 |
• |
Microsoft Internet Information Services (IIS) 5.0 和更高版本 |
• |
Microsoft Active Directory®目录服务 |
• |
Microsoft .NET Framework 1.0版(带 service pack 2)和更高版本 |
• |
Microsoft Visual C#® .NET 开发工具 |
• |
Microsoft SQL Server™ 2000 (带 service pack 2)和更高版本 |
如何使用本章
要想从本章获得最大价值:
• |
您必须具有使用 Visual C# .NET 的编程经验。 |
||||||||||||
• |
您必须具有开发和配置 ASP.NET Web 应用程序的经验。 |
||||||||||||
• |
您必须具有配置 SQL Server 安全性、IIS 安全性,Windows 安全性和 Active Directory 的经验。 |
||||||||||||
• |
阅读 “Introduction”一章。它定义了身份验证、授权和安全通信对分布式 Web 应用程序的重要性。 |
||||||||||||
• |
阅读 “Security Model for ASP.NET Applications”一章。它概述了创建分布式ASP.NET Web 应用程序所使用的体系结构和技术,并着重介绍在本体系结构中何处适用身份验证、授权和安全通信。 |
||||||||||||
• |
阅读 “身份验证和授权”一章。它详细介绍了使用 .NET Remoting 时可用的身份验证和授权机制。 |
||||||||||||
• |
阅读 “安全通信”一章。它介绍了在保护客户端与远程对象间的通信信道时经常要使用的 SSL 和 IPSec。 |
||||||||||||
• |
阅读 “ASP.NET安全性”一章。它深入介绍了与 ASP.NET 相关的安全性问题,当您在 ASP.NET 中承载远程对象时(推荐的方法)其中的很多问题都是相关的。 |
||||||||||||
• |
阅读以下章节,它们介绍了如何实施本章所讨论的很多技术:
|
本页内容
体系结构 | |
.NET Remoting 网关守卫 | |
身份验证 | |
授权 | |
身份验证和授权策略 | |
访问系统资源 | |
访问网络资源 | |
将身份验证的凭证传递给远程对象 | |
传送原调用者 | |
受信任的子系统 | |
安全通信 | |
选择一个主机进程 | |
Remoting 与 Web服务的比较 | |
小结 |
体系结构
图 1 显示在 ASP.NET 中驻留远程对象时的基本 .NET Remoting 体系结构。如果主要关心安全性问题,那么建议使用 ASP.NET 主机和 HTTP通道进行通信,因为它允许远程对象利用 ASP.NET和 IIS 提供的基本安全服务。
有关可能使用的主机和通道类型范围的详细信息以及比较信息,请参见本章后面的“选择一个主机进程” 。
图 1. .NET Remoting 体系结构
客户端与进程内的代理对象进行通信。可以通过远程对象代理设置身份验证凭证(例如,用户名、密码和证书等等)。方法调用通过接收链进行传递(您可以实现自己的自定义接收来执行数据加密),并到达负责通过网络发送数据的传输接收。在服务器端,调用通过相同的管道进行传递,并向对象发出调用。
注 本章中使用的术语“代理” 一词是指客户端进程内的代理对象,客户端通过该对象与远程对象进行通信。不要将它与术语“代理服务器”混淆。
Remoting 接收
当客户端在远程对象上进行方法调用时,.NET Remoting 使用传输通道接收、自定义通道接收和格式化程序通道接收。
传输通道接收
传输通道接收通过网络在客户端与服务器之间传递方法调用。.NET提供了 HttpChannel 和 TcpChannel 类,但是,可以对体系结构进行完全扩展,并且插入您自己的自定义实现方法。
• |
HttpChannel。在将远程对象驻留在 ASP.NET 中时,可以使用此通道。此通道使用 HTTP 协议在客户端和服务器之间发送消息。 |
• |
TcpChannel。在将远程对象驻留在 Microsoft® Windows® 操作系统服务或其他可执行文件中时,可以使用此通道。此通道使用 TCP 套接字在客户端和服务器之间发送消息。 |
• |
自定义通道 。自定义的传输通道可以使用任何基本的传输协议在客户端和服务器之间发送消息。例如,自定义通道可以使用命名管道或邮件槽。 |
比较传输通道接收
下表对两个主要的传输通道接收进行了比较。
表 1. TcpChannel 和 HttpChannel 的比较 HttpChannel | |||
功能 | TCP 通道 | HTTP 通道 | 注释 |
身份验证 |
否 |
是 |
HTTP 通道使用 IIS 和 ASP.NET 提供的身份验证功能,但是不支持 Passport 和表单身份验证。 |
授权 |
否 |
是 |
HTTP 通道支持 IIS 和 ASP.NET 提供的授权功能。这些授权包括 NTFS 权限、URL 授权和文件授权。 |
安全通信 |
是 |
是 |
在 TCP 通道中使用 IPSec。在 HTTP 通道中使用 SSL 和/或 IPSec。 |
自定义接收
可以在通道接收管道内的不同位置上使用自定义通道接收来修改在客户端和服务器之间发送的消息。提供加密和解密功能的通道接收就是一个自定义通道接收的示例。
格式化程序接收
格式化程序接收获取方法调用,并将它们序列化为可通过网络发送的流。.NET 提供两种格式化程序接收:
• |
二进制格式化程序。它使用 BinaryFormatter 类将方法调用打包为一个序列化的二进制流,然后传递该流(使用 HTTP POST)以便向服务器发送数据。二进制格式化程序将 HTTP 请求中的内容类型设置为“application/octet-stream”。 与 SOAP 格式化程序相比,二进制格式化程序可以提供更高的性能。 |
• |
SOAP 格式化程序.它使用 SoapFormatter 类将方法调用打包为 SOAP 消息。在HTTP 请求中将内容类型设置为“text/xml”,并使用 HTTP POST 将其传递到服务器。 |
对驻留在 ASP.NET 中的请求进行剖析
远程对象终结点的地址是由以 .rem 或 .soap 扩展文件名结尾的 URL 指定的(例如 http://someserver/vDir/remoteobject.soap)。当 IIS 收到远程对象(带有 .rem 或 .soap 扩展名)的请求时,就会将它(在 IIS 中)映射到 ASP.NET ISAPI 扩展 (Aspnet_isapi.dll) 中。ISAPI 扩展将该请求转发到 ASP.NET 辅助进程 (Aspnet_wp.exe) 中的应用程序域。图 2 显示了事件的顺序。
图 2. 服务器端处理
图 2 显示了以下事件顺序:
1. |
通过 HTTP 接收 .soap 或 .rem 请求,并将其映射到 Web 服务器上的特定虚拟目录。 |
2. |
IIS 检查 .soap/.rem 映射,然后将文件扩展名映射到 ASP.NET ISAPI 扩展 Aspnet_isapi.dll 中。 |
3. |
ISAPI 扩展将请求传递给 ASP.NET 辅助进程 (Aspnet_wp.exe) 中的应用程序域。如果这是在该应用程序上发送的第一个请求,则创建一个新的应用程序域。 |
4. |
调用 HttpRemotingHandlerFactory 处理程序,然后 remoting 基础结构读取 Web.config 文件中的 <system.runtime.remoting> 部分,它控制服务器端的对象配置(例如,单个调用或单个参数)和授权参数(使用 < authorization> 元素)。 |
5. |
Remoting 基础结构查找包含远程对象的程序集并对其进行实例化。 |
6. |
Remoting 基础结构读取 HTTP 标头和数据流,然后在远程对象上调用该方法。 注:在此进程中,ASP.NET 调用正常的事件处理程序序列。您可以有选择地在 Global.asax 中实现一个或多个事件处理程序,例如, BeginRequest、AuthenticationRequest、AuthorizeRequest 等等。在请求到达远程对象方法时,将代表已验证用户的 IPrincipal 对象存储在 HttpContext.User (和 Thread.CurrentPrincipal) 中,并且可以将它用于授权。例如,使用用户权限要求和编程角色检查。 |
ASP.NET 和 HTTP 通道
Remoting 没有其自己的安全模型。客户端(代理)和服务器(远程对象)之间的身份验证和授权是通过通道和主机进程执行的。可以组合使用以下的主机和通道:
• |
自定义的可执行文件和 TCP 通道。这种组合不提供任何内置的安全功能。 |
• |
ASP.NET 和 HTTP 通道.这种组合通过基本的 ASP.NET 和 IIS 安全功能提供身份验证和授权。 |
ASP.NET 中驻留的对象可以利用 ASP.NET 和 IIS 的基本安全功能。它们包括:
• |
身份验证功能。在 Web.config 中配置 Windows 身份验证功能: <authentication mode="Windows"/> IIS 中的设置控制所使用的 HTTP 身份验证类型。 通用的 HTTP 标头用于对请求进行身份验证。可通过配置远程对象代理为客户端提供凭据,也可以使用默认凭据。 不能使用表单或 Passport 身份验证,因为通道没有提供允许客户端访问 Cookies 的方法,而这是这两种身份验证机制的一个要求。另外,表单和 Passport 身份验证需要重定向到要求客户端交互的登录页面。远程的服务器端对象可用于非交互式的场合。 |
||||||||
• |
授权功能。使用标准的 ASP.NET 授权方法对客户端进行授权。 可配置的授权选项包括:
编程授权选项包括:
|
||||||||
• |
安全通信功能。应该使用 SSL(和/或 IPSec)保护客户端和服务器之间数据传输的安全。 |
更多信息
• |
有关 ASP.NET 和 IIS 提供的身份验证和授权功能的详细信息,请参见“ASP.NET 安全性”一章。 |
• |
有关如何在 ASP.NET/IIS 中驻留对象的详细信息,请参见 Microsoft 知识库文章 Q312107 “HOW TO:Host a Remote Object in Microsoft Internet Information Services”。 |
.NET Remoting 网关守卫
ASP.NET 驻留的远程对象使用的授权点(或者网关守卫)包括:
• |
IIS。如果关闭了匿名身份验证,则 IIS只允许来自特定用户的请求,即它可以在其自己的域或受信任的域中验证这些用户的身份。 IIS 还提供 IP 地址和 DNS 过滤功能。 |
||||
• |
ASP.NET
注要进行文件授权,并不要求使用模拟功能。 FileAuthorizationModule 类只对请求的文件或 URI(例如,.rem 和 .soap)执行访问检查,而不对在远程对象中通过代码访问的文件执行访问检查。 |
||||
• |
用户权限要求和明确的角色检查。除了使用 IIS 和 ASP.NET 可配置的网关守卫外,还可以将用户权限要求(以说明性方式或命令性方式)用作附加的细分访问控制机制。通过使用用户权限检查,您可以根据各个用户的标识和组成员身份(由附加到当前线程的IPrincipal 对象定义)控制对类、方法或个别代码块的访问。 注用于请求角色成员身份的用户权限检查与调用IPrincipal.IsInRole 来测试角色成员身份不同。如果调用者不是指定角色的成员,则前者会出现异常错误,而后者只返回一个布尔值来确认角色成员身份。 |
利用 Windows 身份验证,ASP.NET 能自动将一个代表已验证身份用户的WindowsPrincipal 对象连接到当前的 Web 请求(使用 HttpContext.User)。
身份验证
在结合使用 Remoting 和 ASP.NET Web 应用程序客户端时,就会在 Web 应用程序和远程对象主机上进行身份验证。远程对象主机可以使用的身份验证选项取决于主机类型。
驻留在 ASP.NET 中
当对象驻留在 ASP.NET 中时,可以使用 HTTP 通道在客户端代理和服务器之间传递方法调用。HTTP 通道使用 HTTP 协议对服务器的远程对象代理进行身份验证。
以下列表说明在 ASP.NET 中驻留对象时可以使用的一组身份验证选项:
• |
IIS身份验证选项。匿名、基本、摘要、Windows 集成和证书。 |
• |
ASP.NET 身份验证选项。Windows 身份验证或无(用于自定义的身份验证实现)。 注.NET Remoting 不能直接使用表单和 Passport 身份验证。远程对象调用用于非交互式的场合。如果远程对象的客户端是 .NET Web 应用程序,则 Web 应用程序可以使用表单身份验证和 Passport 身份验证,并将凭据明确地传递给远程对象。在本章后面的“传送原调用者”一节中将对这种类型的方案进一步进行讨论。 |
驻留在 Windows 服务中
当对象驻留在 Windows 服务中时,可以使用 TCP 通道在客户端和服务器之间传递方法调用。它使用基于套接字的原始通信方法。因为套接字没有提供身份验证,所以服务器无法对客户端进行身份验证。
在此方案中,远程对象必须使用自定义身份验证。
自定义身份验证
对于简单的自定义身份验证,远程对象可以公开一个接受用户名和密码的 Login 方法。可以根据存储、检索的角色列表以及发回到客户端的令牌对凭证进行验证,以便在后续请求中使用。在服务器上检索到令牌后,可以使用它来创建一个存储在 Thread.CurrentPrincipal 中的 IPrincipal 对象(包含角色)以便进行授权。
其他自定义身份验证的示例还包括,创建使用提供身份验证的进程间通信通道的自定义传输通道接收(例如,命名管道),或者创建使用 Windows 安全服务提供程序接口 (SSPI) 执行身份验证的通道接收。
更多信息
• |
有关如何在 Windows 服务中驻留对象的信息,请参见“ How to host a remote object in a Windows service ”。 |
• |
有关接收和接收链的详细信息,请查找位于 MSDN 库“Sinks and Sink Chains” 中的 .NET 框架部分。 |
• |
有关如何创建使用 SSPI 的自定义身份验证解决方案的详细信息,请参见以下 MSDN 文章“.NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly”,它位于 http://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp 上。 注本文中的实现过程是一个示例,而不是经过 Microsoft 测试并得到支持的产品。 |
授权
当在 ASP.NET 中驻留对象并且使用 HTTP 通道进行通信时,可以对客户端进行身份验证,并使用以下机制来控制授权:
• |
URL 授权 |
• |
文件授权 |
• |
用户权限要求(说明性和命令性的) |
• |
代码中的 IPrincipal.IsInRole 检查 |
当在 Windows 服务中驻留对象时,TCP 通道不提供任何身份验证。因此,您必须通过创建 IPrincipal 对象并将其存储在 Thread.CurrentPrincipal 中,来执行自定义身份验证并进行授权。
然后,可以使用说明性的用户权限要求检查对远程对象的方法进行注释(如下所示)。
[PrincipalPermission(SecurityAction.Demand, Role="Manager")] void SomeMethod() { }
在对象的方法代码中,也可以使用命令性的用户权限要求和使用 IPrincipal.IsInRole 的明确角色检查。
使用文件授权
您可能需要使用内置的 Windows 访问控制将远程对象作为可保护的 Windows 资源保护起来。如果没有文件授权(使用 Windows ACLs),则您只能使用 URL 授权。
要使用 FileAuthorizationModule 授权访问远程对象终结点(用 .rem 或 .soap URLs 标识),您必须在应用程序的虚拟目录中创建带有 .rem 或 .soap 扩展名的物理文件。
注IIS 使用 .rem 和 .soap 扩展名将对象终结点的请求映射到 ASP.NET ISAPI 扩展 (aspnet_isapi.dll)。通常,它们并不是作为物理文件存在。
为 .NET Remoting 配置文件授权:
1. |
在应用程序虚拟目录的根目录中,创建与 objectUri 具有相同名称的文件(例如,RemoteMath.rem)。 |
2. |
在该文件的顶部添加以下行,然后保存该文件。 <%@ webservice class="YourNamespace.YourClass" ... %> |
3. |
使用 Windows 资源管理器将进行相应配置的 ACL 添加到该文件中。 注可以从用于在服务器上配置远程对象的 web.config 文件中获取 objectUri。查找 <wellknown> 元素,如下例所示。 <wellknown mode="SingleCall" objectUri="RemoteMath.rem" type="RemotingObjects.RemoteMath, RemotingObjects> |
更多信息
有关这些授权机制的详细信息,请参见 “ASP.NET 安全性”一章。
身份验证和授权策略
在许多使用 .NET Remoting 的应用程序中,可以使用远程对象在应用程序中间层中提供业务功能,并且 ASP.NET Web 应用程序可以调用该功能。图 3 中显示了这种设置。
图 3 ASP.NET Web 应用程序调用的远程对象
在这个方案中,使用给 Web 应用程序提供的 IIS 和 ASP.NET 网关守卫来保护对客户端代理的访问;而使用给远程应用程序服务器上 ASP.NET 主机提供的 IIS 和 ASP.NET 网关守卫来保护对远程对象的访问。
.NET Web 应用程序访问的远程对象可以使用两个基本的身份验证和授权策略。
• |
可以在 Web 服务器上对调用者进行身份验证和授权,然后使用模拟将调用者的安全性上下文传递给远程对象。这就是模拟/委派模型。 通过使用这种方法,您可以使用允许委派调用者安全性上下文的 IIS 身份验证机制,例如 Kerberos、基本或表单身份验证(后两个身份验证允许 Web 应用程序访问调用者的凭据),并通过远程对象代理明确地将凭据传递给远程对象。 可以使用 ASP.NET 可配置和编程的网关守卫(包括 URL 授权、文件授权、用户权限要求以及 .NET 角色)在远程对象上对各个调用者进行授权。 |
• |
您可以在 Web 服务器对调用者进行身份验证和授权,然后使用受信任的标识与远程对象进行通信。这就是受信任的子系统模型。 对于这个模型而言,在调用远程对象之前,要求 Web 应用程序对调用者进行身份验证并进行正确授权。可以对远程对象从 Web 应用程序映射的受信任标识收到的任何请求进行处理。 |
更多信息
• |
有关模拟/委派模型和受信任的子系统模型的详细信息,请参见“身份验证和授权”一章中的“授权方法”部分中的“资源访问模型”主题。 |
• |
有关在 Remoting 中使用原调用者模型的详细信息,请参见本章后面的“传送原调用者”。 |
• |
有关在 Remoting 中使用受信任的子系统模型的详细信息,请参见本章后面的“受信任的子系统”。 |
访问系统资源
有关从 ASP.NET 中驻留的远程对象访问系统资源(例如,事件日志和注册表)的详细信息,请参阅“ASP.NET 安全性”一章中的“访问系统资源”。此章讨论的方法和限制也适用于 ASP.NET 所承载的远程对象。
访问网络资源
在从远程对象访问网络资源时,您需要考虑用于响应来自远程计算机的网络身份验证质询的标识。您有三个选项:
• |
进程标识(这是默认标识)。如果在 ASP.NET 中驻留对象,则用于运行 ASP.NET 辅助进程并由 Machine.config 中 < processModel> 元素定义的标识决定了用于资源访问的安全性上下文。 如果在 Windows 服务中驻留对象,则用于运行服务进程的标识(用组件服务 MMC 管理单元配置)决定了用于资源访问的安全性上下文。 |
• |
固定服务标识。例如,通过调用 LogonUser 创建的标识。 注不要将此服务标识与用来运行 Windows 服务的标识混淆起来。固定服务标识是指专为从应用程序访问资源而创建的 Windows 用户帐户。 |
• |
原调用者标识。将 ASP.NET 配置为使用模拟功能,或者在 Windows 服务中使用编程模拟。 |
有关每种方法相对优点的详细信息以及配置细节,请参见“ASP.NET 安全性”一章中的“访问网络资源”。
将身份验证的凭证传递给远程对象
在客户端进程调用远程对象时,它使用代理来完成这一操作。这是一个本地对象,它公开一组与目标对象相同的方法。
指定客户端凭证
如果远程对象驻留在 ASP.NET 中并将该对象配置为使用 Windows 身份验证,则必须使用通道的凭证属性指定用于身份验证的凭证。如果没有明确设置凭据,就会在没有任何凭证的情况下调用远程对象。如果需要使用 Windows 身份验证,这将导致出现 HTTP 状态 401,拒绝访问响应。
使用 DefaultCredentials
如果您要使用驻留远程对象代理(如果调用代理的线程使用模拟功能,则为当前线程令牌)的进程的凭证,则应该将通道的凭证属性设置为进程凭证缓存保存的 DefaultCredentials。
可以在配置文件中指定是否使用 DefaultCredentials,或者通过编程方式设置凭证。
显式配置
在客户端应用程序配置文件(如果客户端应用程序是 ASP.NET Web 应用程序,则为 Web.config)中,将 <channel> 元素的 useDefaultCredentials 属性设置为 true,指定代理在与远程对象进行通信时应该使用 DefaultCredentials。
<channel ref="http" useDefaultCredentials="true" />
编程配置
对于编程配置,请使用以下代码以编程方式确定是否使用 DefaultCredentials。
IDictionary channelProperties; channelProperties = ChannelServices.GetChannelSinkProperties(proxy); channelProperties ["credentials"] = CredentialCache.DefaultCredentials;
使用特定凭证
在调用远程对象时,要使用一组特定的身份验证凭证,请使用以下设置禁止在配置文件中使用默认凭证。
<channel ref="http" useDefaultCredentials="false" />
注编程设置始终覆盖配置文件中的设置。
然后,使用以下代码来配置代理以使用特定的凭证。
IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(proxy); NetworkCredential credentials; credentials = new NetworkCredential("username", "password", "domain"); ObjRef objectReference = RemotingServices.Marshal(proxy); Uri objectUri = new Uri(objectReference.URI); CredentialCache credCache = new CredentialCache(); // Substitute "authenticationType" with "Negotiate", "Basic", "Digest", // "Kerberos" or "NTLM" credCache.Add(objectUri, "authenticationType", credentials); channelProperties["credentials"] = credCache; channelProperties["preauthenticate"] = true;
请求特定的验证类型Request a Specific Authentication Type
按照上面所述,您应该使用 CredentialCache.Add 方法来请求特定的身份验证类型。避免直接使用 NetworkCredential 类,如以下代码所示。
IDictionary providerData = ChannelServices.GetChannelSinkProperties(yourProxy); providerData["credentials"] = new NetworkCredential(uid, pwd);
在生产代码中应该避免出现这种情况,因为您无法控制远程对象主机使用的身份验证机制,因此也无法控制使用凭证的方式。
例如,可能期望得到来自服务器的 Kerberos 或 NTLM 验证要求,但实际却可能收到一个基本要求。在这种情况下,以明文形式将提供的用户名和密码发送到服务器。
设置 preauthenticate 属性
可以将代理的 preauthenticate 属性设置为 true 或 false。如果将其设置为 true(如上述代码所示),则可以提供特定的身份验证凭据,以便通过初始请求传递 WWW-Authenticate HTTP 标头。这将停止 Web 服务器拒绝对原始请求的访问,并对随后的请求执行身份验证。
使用 connectiongroupname 属性
如果 ASP.NET Web 应用程序连接到(驻留在 ASP.NET 中)远程组件并传递原调用者的安全性上下文(通过使用 DefaultCredentials 和模拟或通过设置显式凭据,如上所示),则应该在 Web 应用程序中设置通道的 connectiongroupname 属性。这用于防止未验证身份的新客户端重用到远程组件(该组件与以前的客户端身份验证凭证关联)的已验证身份的旧连接。在使用 HTTP KeepAlives 或出于 IIS 的性能考虑而启用身份验证持续功能时,会出现连接重用。
将 connectiongroupname 属性设置为能够区分调用者的标识符(例如,调用者的用户名)。
channelProperties["connectiongroupname"] = userName;
注如果没有通过 Web 应用程序将原调用者的安全性上下文传递给远程组件,而是使用固定标识(例如,Web 应用程序的 ASP.NET 进程标识)连接到远程组件,则您不需要设置 connectiongroupname 属性。在此方案中,连接安全性上下文在从一个调用者传递到下一个调用者时,保持不变。
下一版本的 .NET 框架将支持基于调用代理对象的线程 SID 的连接池,如果 Web 应用程序正在模拟调用者,则它有助于解决上述问题。.NET Remoting 客户端支持连接池,但 Web 服务客户端不支持。
传送原调用者
本节介绍如何通过 ASP.NET Web 应用程序将原调用者的安全性上下文传递给远程应用程序服务器上 ASP.NET 驻留的远程组件。要在远程对象或后续下游子系统(例如,数据库)中支持每用户的授权,您可能需要完成上述操作。
在图 4 中,通过驻留 ASP.NET Web 应用程序的前端 Web 服务器将原调用者 (Bob) 的安全性上下文传递给远程应用程序服务器上 ASP.NET 驻留的远程对象,并最终将其传递到后端数据库服务器。
图 4. 传递原调用者的安全性上下文
为了给远程对象传递凭据,远程对象客户端(此方案中的 ASP.NET Web 应用程序)必须配置该对象的代理,并明确地设置代理的 credentials 属性。有关说明,请参见本章前面的“将身份验证的凭证传递给远程对象”。
注IPrincipal 对象无法跨越 .NET Remoting 边界传递。
可以使用两种方法来传递调用方的上下文:
• |
传递默认凭证并使用 Kerberos 身份验证(和委派)。该方式要求您在 ASP.NET Web 应用程序内使用模拟,并用从被模拟调用者的安全性上下文中获得的 DefaultCredentials 来配置远程对象代理。 |
• |
传递显式凭证并使用基本身份验证或表单身份验证。该方式不要求在 ASP.NET Web 应用程序内使用模拟。相反,您可以通过编程方式,使用从给 Web 应用程序提供的服务器变量(利用基本身份验证)或 HTML 表单字段(利用表单身份验证)中获取的显式凭据来配置远程对象代理。可以使用基本身份验证或表单身份验证,以明文形式给服务器提供用户名和密码。 |
带有 Kerberos 委派的默认凭据
要使用 Windows 委派,所有计算机(服务器和客户端)都必须运行 Windows 2000 或更高版本。此外,必须将要委派的客户端帐户存储在 Active Directory ™ 目录服务中,并且不能将其标记为“敏感帐户,不能被委派”。
以下各表显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。
配置 Web 服务器 | |
配置 IIS | |
步骤 |
更多信息 |
禁用对 Web 应用程序的虚拟根目录的匿名访问 对 Web 应用程序的虚拟根目录启用 Windows 集成身份验证 |
假定客户端和服务器运行的是 Windows 2000 或更高版本,则可以对 Kerberos 身份验证进行协商。 |
配置 ASP.NET |
|
步骤 |
更多信息 |
将 ASP.NET Web 应用程序配置为使用 Windows 身份验证 |
编辑 Web 应用程序的虚拟目录下的 Web.config 文件。 |
配置 ASP.NET Web 应用程序的模拟 |
编辑 Web 应用程序的虚拟目录下的 Web.config 文件。 |
配置 Remoting(客户端代理) |
|
步骤 |
更多信息 |
配置远程对象代理,以便将默认凭证用于远程对象的所有调用 |
将如下条目添加到 Web.config 文件中: 将从 Web 应用程序的线程模拟令牌中获取凭证。 |
配置远程应用程序服务器 | |
配置 IIS | |
步骤 |
更多信息 |
禁用对 Web 应用程序的虚拟根目录的匿名访问 对 Web 应用程序的虚拟根目录启用 Windows 集成身份验证 |
|
配置 ASP.NET(远程对象主机) |
|
步骤 |
更多信息 |
将 ASP.NET 配置为使用 Windows 身份验证 |
编辑该应用程序的虚拟目录下的 Web.config 文件。 |
配置 ASP.NET 的模拟功能 |
编辑该应用程序的虚拟目录下的 Web.config 文件。 注只有在您想将原调用者的安全性上下文通过远程对象传递给下一个下游子系统(例如数据库)时,才需要执行本步骤。如果在此处启用了模拟功能,资源访问(本地和远程)就会使用模拟的原调用者的安全性上下文。 |
更多信息
有关 Kerberos 委派的详细信息,请参见本指南中的“ 如何做:对 Windows 2000 实现 Kerberos 委派”。
带有基本身份验证或表单身份验证的显式凭证
作为 Kerberos 委派的一个替代方法,您可以在 Web 应用程序中使用基本身份验证或表单身份验证来捕获客户端凭证,然后对远程对象使用基本身份验证(或者集成 Windows 身份验证)。
利用此方式,Web 应用程序可以使用客户端的明文凭证。可以通过远程对象代理将这些凭据传递给远程对象。为此,必须在 Web 应用程序中包含代码以检索客户端凭据并配置远程对象代理。
基本身份验证
使用基本身份验证,Web 应用程序可在服务器变量中使用原调用方的凭证。以下代码说明如何检索凭证并配置远程对象代理。
// Retrieve client's credentials (available with Basic authentication) string pwd = Request.ServerVariables["AUTH_PASSWORD"]; string uid = Request.ServerVariables["AUTH_USER"]; // Associate the credentials with the remote object proxy IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(proxy); NetworkCredential credentials; credentials = new NetworkCredential(uid, pwd); ObjRef objectReference = RemotingServices.Marshal(proxy); Uri objectUri = new Uri(objectReference.URI); CredentialCache credCache = new CredentialCache(); credCache.Add(objectUri, "Basic", credentials); channelProperties["credentials"] = credCache; channelProperties["preauthenticate"] = true;
注上述代码中的 NetworkCredential 构造函数是随用户 ID 和密码提供的。要避免对域名进行硬编码,在配置基本身份验证时,可以在 IIS 中的 Web 服务器上配置默认域。
表单身份验证
使用表单身份验证,Web 应用程序可在表单各个字段中(而不是在服务器变量中)使用原调用方的凭证。在这种情况下,请使用以下代码。
// Retrieve client's credentials from the logon form string pwd = txtPassword.Text; string uid = txtUid.Text; // Associate the credentials with the remote object proxy IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(proxy); NetworkCredential credentials; credentials = new NetworkCredential(uid, pwd); ObjRef objectReference = RemotingServices.Marshal(proxy); Uri objectUri = new Uri(objectReference.URI); CredentialCache credCache = new CredentialCache(); credCache.Add(objectUri, "Basic", credentials); channelProperties["credentials"] = credCache; channelProperties["preauthenticate"] = true;
以下各表显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。
配置 Web 服务器 | ||
配置 IIS | ||
步骤 |
更多信息 |
|
要使用基本身份验证,请禁用对您 Web 应用程序的虚拟根目录的匿名访问,并选择基本身份验证 - 或者 - 要使用表单身份验证,请启用匿名访问 |