远程处理中的安全性

通常,使用 .NET Framework 远程处理的应用程序比本地应用程序有着一系列更为复杂的安全问题。

加强分布式应用程序的安全给我们带来一个难题,如不求助于将会降低性能的手段,很难将其克服。如果通信的一端正在侦听调用,任何了解侦听终结点的未经授权的客户端都可以传递一些序列化的信息,这样,可以在另一终结点反序列化和调用该信息。只有通过相互验证身份并将内容加密,才能合理地确保通信是在信任的组件之间进行的。因此,您应该首先评估远程处理应用程序的安全要求,然后评估性能要求。您应该根据应用程序所需的数据完整性的程度,不通过身份验证和加密来公开数据和终结点。

远程处理委托说明了这一问题。由于委托可以包装静态方法(静态方法永远不会远程执行)的类型信息,因此服务器应用程序必须始终声明采用自定义参数的自定义委托类型,这些参数在一起永远不会匹配可以在服务器计算机上调用的静态方法。应该永远不要允许客户端定义服务器可能会反序列化的任何类型并将其传递给应用程序。

当设计采用 .NET Framework 远程处理基础结构的安全分布式应用程序时,一个非常重要的环节是确保您知道所需要的安全级别以及在哪里需要它。本节基于某些设计决策说明各种实现安全性的方法。这里并没有给出所有方案,但是这些主题是做出决策的好起点。

代码访问安全性

代码访问安全性基于计算机管理员设置的安全策略控制可执行代码对资源和操作的访问。但是,由于代码访问安全性不审核跨越远程连接的堆栈,因此,远程处理应用程序的开发人员应清楚地知道,远程处理基础结构需要完全信任才能在客户端或服务器上执行。任何远程处理应用程序的未经授权的使用都提供对 FullTrust 权限未经授权的访问。

警告

您决不应该尝试为 AppDomain 对象创建可远程处理的包装。如果这样做,就可能能够在远程发布对该 AppDomain 的引用,这会在远程公开 AppDomain.CreateInstance 方法(或其他方法),并因而有效破坏该 AppDomain 的任何代码访问安全性。连接到远程 AppDomain 的未经授权的客户端可能能够访问 AppDomain 本身可以访问的任何资源。实际上,您不应该对以下类型创建可远程处理的包装:扩展 MarshalByRefObject 的任何类型;实现可以由未经授权的客户端用来绕过安全系统的方法的任何类型。

备注

从更为一般的意义上来讲,几种系统类型扩展 MarshalByRefObject,但也在运行时执行安全检查以防止应用程序域之外的任何对象在远程调用该 MarshalByRefObject 类型的对象。AppDomain 和 System.Windows.Forms.Form 就是此系统类型的两个示例。这样来理解会容易一些:您可以扩展 MarshalByRefObject 并在远程获取引用,但这对于这些特殊类型则不适用。您可能想要将进程内引用包装在另一个可远程处理的类型中,但这样做会在无意中绕过代码访问安全机制,因此决不应该这样做。

远程处理应用程序中的安全性考虑事项

一般而言,根据您的特定方案,在分布式应用程序中有两个您可能需要考虑的安全性领域。您或者需要确保通信信道和消息本身的安全,或者需要确保应用程序不会受到不正确的使用。您也可能需要在一定程度上确保这两者。

通常,要确保通信信道的安全,您必须或者加密信道本身,或者在流的一端将消息的内容加密并在另一端将其解密,或者采用上述两种安全措施。消息的内容可能要求完整性检查,以帮助确定是否有人破坏它。客户端或服务器(或者这两者)的身份可能也需要得到确认。

首先,您应该始终对客户端进行身份验证,以确认它们有权使用资源。其次,您应该对所有对话进行加密,以在传输期间保护数据。HttpChannelTcpChannel 均完全支持这两个步骤。(因为 IPC 信道只适用于同一台计算机,所以,它不支持加密,但它支持 Windows 身份验证。)

对于上述两个规则也有一些例外情况。如果十分看重性能要求并且数据价值不甚重要,以致数据的获取或操作变得相对不很重要,则可以取消加密。当在加密的网络(例如由 IPsec 确保安全的网络)上进行通信时,也可以禁用加密。

您还可以通过记录用户的行为以重新构造之后的使用模式,保护应用程序不被未经授权的用户使用。

警告

.NET Framework 远程处理在默认情况下不进行身份验证或加密。因此,建议您在与客户端或服务器进行远程交互之前,采取任何必要的措施以确认它们的身份。因为 .NET Framework 远程处理应用程序需要 FullTrust 权限才能执行,所以,未经授权的客户端如果被授予访问您服务器的权限,该客户端就可能像完全受信任的客户端一样执行代码。应始终验证终结点的身份并将通信流加密。您可以通过在 Internet 信息服务 (IIS) 中承载远程类型,或者通过生成自定义信道接收对来完成这项工作,执行上述安全防范措施。在 .NET Framework 版本 2.0 中,您不再需要生成自定义接收器来确保通信的安全。身份验证和加密功能(通过为 TCP 信道设置 secure = true 来启用这两项功能)可以实现安全地通信。TCP 信道现在允许您对所连接的用户进行身份验证,对网络上的数据进行加密,以及确定所连接的客户端的身份和 IP 地址。

请参见

参考

RemotingConfiguration
ChannelServices
上下文
MethodCall
RemotingServices

概念

使用 HTTP 信道进行身份验证

其他资源

.NET Framework 远程处理概述
基于角色的安全性
代码访问安全性