注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天涯倦客的博客

祝福你朋友永远快乐!

 
 
 

日志

 
 

.NET Remoting 安全性  

2011-03-02 15:33:40|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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)和更高版本

如何使用本章

要想从本章获得最大价值:

本页内容

体系结构 体系结构
.NET Remoting 网关守卫 .NET Remoting 网关守卫
身份验证 身份验证
授权 授权
身份验证和授权策略 身份验证和授权策略
访问系统资源 访问系统资源
访问网络资源 访问网络资源
将身份验证的凭证传递给远程对象 将身份验证的凭证传递给远程对象
传送原调用者 传送原调用者
受信任的子系统 受信任的子系统
安全通信 安全通信
选择一个主机进程 选择一个主机进程
Remoting 与 Web服务的比较 Remoting 与 Web服务的比较
小结 小结

体系结构

1 显示在 ASP.NET 中驻留远程对象时的基本 .NET Remoting 体系结构。如果主要关心安全性问题,那么建议使用 ASP.NET 主机和 HTTP通道进行通信,因为它允许远程对象利用 ASP.NET和 IIS 提供的基本安全服务。

有关可能使用的主机和通道类型范围的详细信息以及比较信息,请参见本章后面的“选择一个主机进程” 。

f11sn01

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 显示了事件的顺序。

f11sn02

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 中实现一个或多个事件处理程序,例如, BeginRequestAuthenticationRequestAuthorizeRequest 等等。在请求到达远程对象方法时,将代表已验证用户的 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 授权方法对客户端进行授权。

    可配置的授权选项包括:

    • URL 授权。

    • 文件授权(它需要特定的配置。有关说明,请见本章后面的“使用文件授权”)。

    编程授权选项包括:

    • 用户权限要求(说明性和命令性的)。

    • 使用 IPrincipal.IsInRole 进行明确的角色检查。

  • 安全通信功能。应该使用 SSL(和/或 IPSec)保护客户端和服务器之间数据传输的安全。

更多信息

.NET Remoting 网关守卫

ASP.NET 驻留的远程对象使用的授权点(或者网关守卫)包括:

  • IIS。如果关闭了匿名身份验证,则 IIS只允许来自特定用户的请求,即它可以在其自己的域或受信任的域中验证这些用户的身份。 IIS 还提供 IP 地址和 DNS 过滤功能。

  • ASP.NET

    • UrlAuthorizationModule。可以配置应用程序 Web.config 中的< authorization> 元素,控制哪些用户和用户组可以访问应用程序。授权是以存储在 HttpContext.User 中的 IPrincipal 对象为基础。

    • FileAuthorizationModuleFileAuthorizationModule 可用于远程组件,但这需要进行特定的配置。有关说明,请参见本章后面的“使用文件授权”。

    注要进行文件授权,并不要求使用模拟功能。

    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) 执行身份验证的通道接收。

更多信息

授权

当在 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 中显示了这种设置。

f11sn03

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 驻留的远程对象,并最终将其传递到后端数据库服务器。

f11sn04

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 身份验证进行协商。
注意:如果在 Windows 2000 上使用 Microsoft Internet Explorer 6,则它默认使用 NTLM 身份验证,而不是所需的 Kerberos 身份验证。要启用 Kerberos 委派,请参见 Microsoft 知识库文章 Q299838 “Unable to Negotiate Kerberos Authentication after upgrading to Internet Explorer 6”。

配置 ASP.NET

 

步骤

更多信息

将 ASP.NET Web 应用程序配置为使用 Windows 身份验证

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <authentication> 元素设置为: 元素设置为:

<authentication mode="Windows" /> 

配置 ASP.NET Web 应用程序的模拟

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <identity> 元素设置为:

<identity impersonate="true" />

配置 Remoting (客户端代理)

 

步骤

更多信息

配置远程对象代理,以便将默认凭证用于远程对象的所有调用

将如下条目添加到 Web.config 文件中:

将从 Web 应用程序的线程模拟令牌中获取凭证。

配置远程应用程序服务器

配置 IIS

步骤

更多信息

禁用对 Web 应用程序的虚拟根目录的匿名访问

对 Web 应用程序的虚拟根目录启用 Windows 集成身份验证

 

配置 ASP.NET (远程对象主机)

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <authentication>元素设置为:<authentication mode="Windows" />

配置 ASP.NET 的模拟功能

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <identity> 元素设置为:<identity impersonate="true" />

注只有在您想将原调用者的安全性上下文通过远程对象传递给下一个下游子系统(例如数据库)时,才需要执行本步骤。如果在此处启用了模拟功能,资源访问(本地和远程)就会使用模拟的原调用者的安全性上下文。
如果您只要求在远程对象中对每个用户进行授权检查,则无需在此处启用模拟功能。

更多信息

有关 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 应用程序的虚拟根目录的匿名访问,并选择基本身份验证

- 或者 -

要使用表单身份验证,请启用匿名访问

基本身份验证和表单身份验证都应和 SSL 配合使用,才能保护通过网络传送的明文凭证。如果您使用基本身份验证,则应该将 SSL 用于所有页面(而不仅仅是初始登录页面),因为在每个请求中都传递基本身份验证凭证。类似地,如果您使用表单身份验证,则应该将 SSL 用于所有页面,以保护初始登录中的明文凭证以及在后续请求中传递的身份验证票。

配置 ASP.NET

 

步骤

更多信息

如果您使用基本身份验证,则将您的 ASP.NET Web 应用程序配置为使用 Windows 身份验证
- 或者 -

如果您使用表单身份验证,则将您的 ASP.NET Web 应用程序配置为使用表单身份验证

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <authentication> 元素设置为: <authentication mode="Windows" />
- 或者 -

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <authentication> 元素设置为:<authentication mode="Forms" />

禁用 ASP.NET Web 应用程序内的模拟功能

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <identity>元素设置为: <identity impersonate="false" />

这相当于没有 <identity> 元素。
因为通过远程对象代理将用户凭证明确传递给远程对象,所以不需要使用模拟功能。

配置 Remoting (客户端代理)

 

步骤

更多信息

配置 Remoting 代理,以便将默认凭证用于远程对象的所有调用

将如下条目添加到 Web.config 文件中: <channel ref="http" useDefaultCredentials="false" />

您不希望使用默认凭据(因为将 Web 应用程序配置为不使用模拟,因此,这将导致使用 ASP.NET 进程标识的安全性上下文)。

编写代码,以便在远程对象代理中捕获和明确地设置凭据

请参考前面的代码片段。

配置应用程序服务器

配置 IIS

步骤

更多信息

禁用对应用程序的虚拟根目录的匿名访问

启用基本身份验证





通过在应用程序服务器(远程对象)上使用基本身份验证,远程对象可以将原调用者的安全性上下文传递到数据库(因为调用方的用户名和密码采用明文形式,并且可以用来响应来自数据库服务器的网络身份验证质询)。
如果不需要将原调用者的安全性上下文传递到远程对象以外,则考虑在应用程序服务器上将 IIS 配置为使用 Windows 集成身份验证,因为这可提供更高的安全性–(不通过网络传递凭证,并且不给应用程序提供凭证)。

配置 ASP.NET (远程对象主机)

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <authentication>元素设置为:<authentication mode="Windows" />

配置 ASP.NET 的模拟功能Configure ASP.NET for impersonation

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <identity>元素设置为:<identity impersonate="true" />

只有在您想将原调用者的安全性上下文通过远程对象传递给下一个下游子系统(例如数据库)时,才需要执行本步骤。如果在此处启用了模拟功能,资源访问(本地和远程)就会使用模拟的原调用者的安全性上下文。
如果您只要求在远程对象中对每个用户进行授权检查,则无需在此处启用模拟功能。

受信任的子系统

受信任的子系统模型提供了一种替代(且更易于实现的)方式来传递原调用者的安全性上下文。在该模型中,远程对象主机和 Web 应用程序之间存在信任边界。远程对象首先信任 Web 应用程序对调用者正确地进行身份验证和授权,然后才允许向远程对象发送请求。在远程对象主机中不对原调用者进行任何身份验证。远程对象主机对 Web 应用程序用来与远程对象通信的固定受信任标识进行身份验证。在大多数情况下,这是 ASP.NET Web 应用程序的进程标识。

5 显示了受信任的子系统模型。该图还显示了两种可能的配置。第一种配置使用 ASP.NET 主机和 HTTP 通道,而第二种配置使用 Windows 服务主机和 TCP 通道。

f11sn05

5. 受信任的子系统模型

传送调用方的标识

如果您使用的是受信任的子系统模型,则可能仍然需要传送原调用者的标识(名称,不是安全性上下文),例如,用于在数据库中进行审核。

通过使用可用于从数据库检索用户特定数据的方法、存储过程参数和受信任的查询参数(如下面的示例所示),可以在应用程序级传送该标识。

SELECT x,y,z FROM SomeTable WHERE UserName = "Bob"      

选择主机

受信任的子系统模型意味着远程对象主机不对原调用方进行身份验证。但是,它仍需对其中间客户端(此方案中的 ASP.NET Web 应用程序)进行身份验证(和授权),以防止未经授权的应用程序向远程对象发出请求。

如果您在 ASP.NET 中驻留对象并使用 HTTP 通道,则可以使用 Windows 集成身份验证对 ASP.NET Web 应用程序进程标识进行身份验证。

如果您在 Windows 服务中驻留对象,则可以使用具有更高性能的 TCP 通道,但是该通道不提供身份验证功能。在此方案中,可以在 Web 服务器和应用程序服务器之间使用 IPSec。可以制订只允许 Web 服务器与应用程序服务器进行通信的 IPSec 策略。

配置步骤

以下各表显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。

配置 Web 服务器

配置 IIS

步骤

更多信息

配置 IIS 身份验证

Web 应用程序可以使用任何形式的验证方法来验证原调用者。

配置 ASP.NET

 

步骤

更多信息

配置身份验证并确保禁用模拟功能

编辑 Web 应用程序的虚拟目录下的 Web.config 文件。
将 <authentication> 元素设置为“Windows”、“Forms”和“Passport”。<authentication mode="Windows|Forms|Passport" />

将 <identity> 元素设置为:<identity impersonate="false" />

 

(或者删除 < identity> 元素)

重置用于运行 ASP.NET 的 ASPNET 帐户的密码,或者创建一个权限最少的域帐户来运行 ASP.NET,并在 Web.config 文件内的 <processModel> 元素上指定帐户详细信息

有关如何从 ASP.NET 访问网络资源(包括远程对象)以及选择和配置 ASP.NET 进程帐户的详细信息,请参见“ASP.NET 安全性”一章中的“访问网络资源”和“ASP.NET 的进程标识”。

配置 Remoting (客户端代理)

 

步骤

更多信息

配置 Remoting 代理,不要将默认凭证用于远程对象的所有调用

将如下条目添加到 Web.config 文件中:<channel ref="http" useDefaultCredentials="true" />

因为 Web 应用程序没有使用模拟,所以如果使用默认凭证,就会导致将 ASP.NET 进程标识用于远程对象的所有调用。

配置应用程序服务器

如果使用的是 ASP.NET 主机,则执行以下步骤。

配置 IIS

步骤

更多信息

禁用对应用程序的虚拟根目录的匿名访问

启用 Windows 集成的身份验证

 

配置 ASP.NET (远程对象主机)

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <authentication>元素设置为:<authentication mode="Windows" />

禁用模拟

编辑该应用程序的虚拟目录下的 Web.config 文件。
将 <identity> 元素设置为:<identity impersonate="false" />

使用 Windows 服务主机

如果使用的是 Windows 服务主机进程,则必须创建一个 Windows 帐户以运行该服务。远程对象将使用该帐户提供的安全性上下文来访问所有本地和远程资源。

要访问远程 Microsoft SQL Server?? 数据库(利用 Windows 身份验证),您可以使用权限最少的域帐户;也可以使用本地帐户,然后在数据库服务器上创建一个重复帐户(具有相同的用户名和密码)。

安全通信

安全通信是指在通过网络传送消息时确保消息的完整性和机密性。可以使用基于平台的方法来保护通信的安全并使用 SSL 或 IPSec;也可以使用消息级方法并开发自定义的加密接收,以便对整个消息或消息的选定部分进行加密。

平台级选项

可以考虑两个平台级选项以保护在客户端和远程组件之间传送的数据安全:

  • SSL

  • IPSec

如果远程对象驻留在 ASP.NET 中,则可以使用 SSL 来保护客户端和服务器之间的通信通道。这要求驻留远程对象的计算机具有服务器身份验证证书。

如果远程对象驻留在 Windows 服务中,则可以在客户端和主机(服务器)之间使用 IPSec,也可以开发自定义的加密接收。

消息级选项

由于 .NET Remoting 体系结构具有可扩展性,因此,您可以开发自定义接收并将其插入到处理管道中。要提供安全的通信,可以开发自定义接收,以便对发送到和来自远程对象的消息数据进行加密和解密。

这种方法的优点是,您可以有选择地加密消息的一部分。这与平台级方法正好相反,平台级方法对客户端和服务器之间发送的所有数据进行加密.

更多信息

有关 SSL 和 IPSec 的详细信息,请参见“安全通信”一章。

选择一个主机进程

要远程访问的对象必须在主机可执行文件中运行。主机侦听传入请求,并向对象发出调用.所选的主机类型影响称为“通道”的消息传输机制。选择的通道类型影响身份验证、授权、安全通信和解决方案的性能。

HTTP 通道提供更好的安全性选项,但 TCP 通道提供更高的性能。

可以使用以下主要选项来驻留远程对象:

  • 驻留在 ASP.NET中

  • 驻留在 Windows 服务中

  • 驻留在控制台应用程序中

建议

从安全的角度出发,要充分利用 ASP.NET 和 IIS 提供的安全基础结构,建议将远程对象驻留在 ASP.NET 中。这要求客户端通过 HTTP 通道与远程对象进行通信。驻留在 ASP.NET 中的远程对象可以使用 ASP.NET 和 IIS 身份验证、授权和安全通信功能。

如果主要关心性能(而不是安全性)问题,则考虑将远程对象驻留在 Windows 服务中。

驻留在 ASP.NET 中

在将远程对象驻留在 ASP.NET 中时:

  • 使用 HTTP 协议来访问该对象。

  • 它具有一个可通过 URL 访问的终结点。

  • 它位于 Aspnet_wp.exe 辅助进程内的应用程序域中。

  • 它继承 IIS 和 ASP.NET 提供的安全功能。

优点

如果将远程对象驻留在 IIS 中,则您可以获得以下优势:

  • 直接使用 IIS 和 ASP.NET 提供的身份验证、授权和安全通信功能。

  • 可以使用 IIS 的审核功能。

  • ASP.NET 辅助进程始终运行。

  • 通过使用 Machine.config 中的 <processModel> 元素,对驻留的可执行文件进行更严格的控制。可以控制线程管理、容错性和内存管理等等。

  • 可以在远程对象前面创建 Web 服务外层。

缺点

如果使用 ASP.NET 驻留远程对象,则应该了解它的以下缺点:

  • 它要求使用的 HTTP 通道比 TCP 通道慢。

  • ASP.NET 不加载用户配置文件。多种加密技术(包括 DPAPI)可能需要使用用户配置文件。

  • 如果从 ASP.NET Web 应用程序中运行的代码访问对象,则可能需要使用基本身份验证。

驻留在 Windows 服务中

如果将远程对象驻留在 Windows 服务中,则在服务进程内包含的应用程序域中激活远程对象。您不能使用 HTTP 通道,而必须使用 TCP 通道。TCP 通道支持以下安全功能:

  • 身份验证功能

    您必须提供自定义的身份验证解决方案。选项包括:

    • 使用 SSPI 的基本身份验证服务。可以创建使用 Windows SSPI 凭据和上下文管理 API 的通道接收,对调用方进行身份验证并有选择地模拟调用者。该通道接收位于 TCP 通道的顶端。配合 TCP 通道使用的 SSPI 允许客户端和服务器交换身份验证信息。在进行身份验证后,客户端和服务器可以发送消息并确保消息的机密性和完整性。

    • 使用支持身份验证的基本传输(例如,命名管道)。命名管道通道将命名管道用作传输机制。它给调用者提供了身份验证功能,并且还在管道中引入基于 Windows ACL 的安全功能以及调用方的模拟功能。

  • 授权功能

    仅当实现自定义的身份验证解决方案后,才能使用授权功能。

    • 如果您能够模拟用户(例如,通过使用基本的命名管道传输),则可以使用 WindowsPrincipal.IsInRole

    • 如果您能够创建 IPrincipal 对象代表已验证身份的客户端,则可以使用 .NET 角色(通过用户权限要求和使用 IPrincipal.IsInRole 的明确角色检查)。

  • 安全通信功能

    您有两个选项:

    • 使用 IPSec 保护客户端和服务器之间的数据传输安全。

    • 创建执行不对称加密的自定义通道接收。此选项将在本章后面讲述。

优点

如果将远程对象驻留在 Windows 服务中,则可以获得以下优势:

  • 对主机进程进行严格的激活控制

  • 继承 Windows 服务体系结构的优点

  • 无需在应用程序的中间层引入 IIS

  • 自动加载用户配置文件

  • 与客户端使用二进制编码数据通过 TCP 通道进行通信的功能相当

缺点

如果使用 Windows 服务来驻留远程对象,则应该了解它的以下缺点:

  • 必须提供自定义的身份验证和授权解决方案。

  • 必须提供安全的通信解决方案。

  • 必须提供审核解决方案。

驻留在控制台应用程序中

如果将远程对象驻留在控制台应用程序中,则在控制台应用程序进程内包含的应用程序域中激活远程对象。您不能使用 HTTP 通道,而必须使用 TCP 通道。

建议在生产解决方案中不要使用这种方法。

优点

虽然这种方法没有多少优点,但它在中间层的确不需要使用 IIS。不过,仅建议在开发和测试环境中使用这种方法,不要在生产环境中使用。

缺点

如果将远程对象驻留在自定义的可执行文件中,则应该了解它的以下缺点:

  • 主机必须手动启动,并且在交互式登录会话中运行(不建议使用)。

  • 没有容错功能。

  • 必须提供自定义的身份验证和授权功能。

  • 没有审核功能。

Remoting 与 Web服务的比较

.NET 提供多种不同的方法使客户端能够与远程对象进行通信,其中包括使用 Web 服务。

如果需要异类系统之间具有互操作性,则最好选择使用开放式标准(例如 SOAP、XML 和 HTTP)的 Web 服务方法。另一方面,如果您正在创建服务器到服务器的 intranet 解决方案,则 Remoting 为您提供以下功能:

  • 由于可以远程控制任何 .NET 类型(包括使用 Microsoft C#? 开发工具和 Microsoft Visual Basic? .NET 开发系统创建的自定义类型),因此各种对象保持不变。

    这包括类、类层次结构、接口、域、属性、方法和委派、数据集、哈希值表等等。

  • 可以由按值和按引用来封送对象。

  • 对象生命周期管理是基于租期进行的。

  • 高性能,尤其是使用 TCP 通道和二进制格式化程序提供的性能。

  • 它允许您使用网络负载平衡功能构建负载平衡的中间层。

表 2. Remoting 和 Web 服务的主要差别

远程处理

Web 服务

状态满或无状态,基于租期的对象生命周期管理

所有方法调用都是无状态的

不需要 IIS
(但是出于安全方面的考虑,建议驻留在 IIS/ASP.NET 中)

必须在服务器上安装 IIS

支持所有的托管类型

支持数量有限的数据类型。有关 ASP.NET Web 服务支持的类型的详细信息,请参见 MSDN 上的“.NET Framework Developer's Guide”。

可以按引用或按值传递对象

无法传递对象

包含可扩展的体系结构,并不限定于 HTTP 或 TCP 传输

限定于 HTTP 上的 XML

可以将自定义的处理接收插入到消息处理管道中

无法修改消息

SOAP 实现受限制,并且只能使用 RPC 编码

SOAP 实现可以使用 RPC 或文档编码,并且可以实现与其他 Web 服务平台的完全互操作。
有关详细信息,请参阅 MSDN 文章“Distributed Application Communication”中的“Message Formatting and Encoding”(消息格式设置和编码)一节。

紧密集成

松散集成

小结

.NET Remoting 不提供其自己的安全模型。然而,通过将远程对象驻留在 ASP.NET 中并使用 HTTP 通道进行通信,远程对象可以使用 IIS 和 ASP.NET 提供的基本安全服务。比较而言,TCP 通道和自定义的主机可执行文件可提供更高的性能,但这种组合不提供内置的安全功能。

  • 若要对客户端进行身份验证,请使用 HTTP 通道,在 ASP.NET 中驻留对象,以及在 IIS 中禁用匿名访问。

  • 如果您不担心客户端身份验证问题,请使用 TCP 通道,它可以提供更高的性能。

  • 如果您使用 TCP 通道,请使用 IPSec 保护客户端和服务器之间的通信通道。使用 SSL 来保护 HTTP 通道。

  • 如果您需要对远程资源进行受信任的调用,请将组件驻留在 Windows 服务中,而不是驻留在控制台应用程序中。

  • IPrincipal 对象无法跨越 .NET Remoting 边界传递。 可以考虑实现您自己的 IPrincipal 类(可以进行序列化)。如果您执行上述操作,则要注意攻击客户端可以很容易地骗过 IPrincipal 对象并将它发送给远程对象。另外,如果您在 Remoting 中实现您自己的 IPrincipal 类,则要慎用 IlogicalThreadAffinitive

  • 始终不要向 Internet 公开远程对象。在这种情况下,请使用 Web 服务。

    应该仅在 Intranet 中使用 .NET Remoting。应该使用内部方式从 Web 应用程序访问对象。即使对象驻留在 ASP.NET 中,也不要向 Internet 客户端公开它们,因为客户端必须是 .NET 客户端。

  评论这张
 
阅读(1921)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017