在 Internet 信息服务 (IIS) 中承载远程对象

本主题介绍一项传统技术,保留该技术是为了向后兼容现有的应用程序,不建议对新的开发使用该技术。现在应该使用  Windows Communication Foundation (WCF) 来开发分布式应用程序。

若要在 Internet 信息服务 (IIS) 中承载远程对象,必须对远程对象进行配置。配置远程对象通常有两种方式:一是在配置文件中配置;二是以编程方式在宿主应用程序代码中配置。当远程对象承载于 IIS 中时,既可以将配置信息置于 Web.config 文件中,也可以通过编程方式在 Global.asax 文件中的 Application_Start 方法中配置该远程对象。

若要使用配置文件配置远程对象,请执行下列操作:

  • 将配置信息置于所选用的 IIS 虚拟目录中的 Web.config 文件中。

  • 将可远程处理的类型实现置于 \bin 目录中(或使用全局程序集缓存工具 (Gacutil.exe) 将其置于全局程序集缓存中)。

指定 Web.config 文件时,不支持下列操作:

  • 指定应用程序名称,虚拟目录的名称将变为应用程序的名称。

  • 使用供 .NET 远程处理配置使用的 Web.config 文件中的 <debug> 元素。

  • 使用 HttpChannel 之外的任何信道。

  • 使用 Web.config 文件和 <client> 元素可自动配置客户端 Web 应用程序。如果要将 IIS 用作远程处理客户端,必须在 Global.asax 文件中的 Application_Start 方法中调用 RemotingConfiguration.Configure

Web.config 文件仍然包含系统必须了解的有关类型的基本信息,但必须对部分声明略加更改才能适应宿主环境。例如,您可以自定义配置某个特定的 HttpChannel,但不应为该信道指定端口。这是因为,如果 ASP.NET 创建了另一个应用程序域来处理负载,远程处理配置将导致新应用程序域也尝试侦听同一端口,从而引发异常。例如,对于由 IIS 承载的 .NET 远程对象,其 Web.config 文件可能类似于下面的代码示例。在本示例中,没有必要包括信道配置行,但需要设置信道属性(本例中为 priority 属性)。

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="Singleton" 
               type="ServiceClass, ServiceClassAssemblyName"
                objectUri="ServiceClass.rem"
            />
         </service>
         <channels>
            <channel 
               name="MyChannel" 
               priority="100" 
               ref="http"
            />
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>
y0hedwet.note(zh-cn,VS.100).gif注意:
请勿为此处列出的任何信道指定端口。如果需要让应用程序侦听某个特定的端口,请使用 Internet 服务管理器指定 IIS 对该端口进行侦听。已配置的信道将自动用于处理通过该端口提交的远程请求。

若要在 IIS 中成功承载服务器激活的(即 <wellknown>)对象,必须使用以 .rem 或 .soap 结尾的对象统一资源标识符 (URI)。其他宿主应用程序域没有此类要求。若要使用 Soapsuds 工具 (Soapsuds.exe) 为 IIS 中承载的服务器激活对象生成元数据,请将以参数形式传递给 Soapsuds.exe 的 URL 设置为以下形式:

http://< 计算机 >:< 端口 >/< 虚拟目录 >/< 对象 URI >?wsdl

对于 IIS 中承载的客户端激活的对象或任何其他应用程序域,无需使用任何形式的对象 URI。以参数形式传递给 Soapsuds.exe 的 URL 采用以下形式:

http://< 计算机 >:< 端口 >/< 虚拟目录 >/RemoteApplicationMetadata.rem?wsdl

IIS 中的编程配置通过 Global.asax 页完成。下面的示例演示的配置与前面演示的配置文件相同,但这次使用的是 Global.asax 文件。

<%@ Application Language="VB" %>
<%@ Assembly Name="Server" %>
<%@ Import Namespace="System.Runtime.Remoting" %>
<%@ Import Namespace="System.Runtime.Remoting.Channels" %>
<%@ Import Namespace="System.Runtime.Remoting.Channels.Http" %>
<%@ Import Namespace="Server" %>

Sub Application_Start()
   Dim props = New Hashtable() As IDictionary
   props("name") = "MyChannel" 
   props("priority") = "100" 
   ' Nothing entries specify the default formatters.
   Dim channel As New HttpChannel( _
      props, _
      Nothing, _
      Nothing _
   )
   ChannelServices.RegisterChannel(channel)
   Dim WKSTE As New WellKnownServiceTypeEntry( _
      GetType(ServiceClass), _
      "HttpService", _
      WellKnownObjectMode.SingleCall
   )
   RemotingConfiguration.RegisterWellKnownServiceType(WKSTE)
End Sub
<%@ Application Language="C#" %>
<%@ Assembly Name="Server" %>
<%@ Import Namespace="System.Runtime.Remoting" %>
<%@ Import Namespace="System.Runtime.Remoting.Channels" %>
<%@ Import Namespace="System.Runtime.Remoting.Channels.Http" %>
<%@ Import Namespace="Server" %>
void Application_Start(){
   IDictionary props = new Hashtable();
   props["name"] = "MyChannel";
   props["priority"] = "100";
   // Null entries specify the default formatters.
   HttpChannel channel = new HttpChannel(
      props, 
      null, 
      null
   );
   ChannelServices.RegisterChannel(channel);
   WellKnownServiceTypeEntry WKSTE = new WellKnownServiceTypeEntry(
      typeof(ServiceClass),
      "HttpService", 
      WellKnownObjectMode.SingleCall
   );
   RemotingConfiguration.RegisterWellKnownServiceType(WKSTE);
} 

必须将下面的条目置于 Web.config 文件中,才能确保引用所需的程序集:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
      <compilation>
        <assemblies>
          <add assembly="System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </assemblies>
      </compilation>
  </system.web>
</configuration>

有关完整的示例,请参见远程处理示例:在 Internet 信息服务 (IIS) 中承载

在 .NET 远程处理中使用 SSL 证书

证书用于标识特定的计算机,计算机名称位于证书的公用名中。但是,很容易更改计算机的名称或在客户端配置文件中使用“localhost”,这会在客户端和服务器证书公用名之间造成不匹配。在 .NET Framework 1.0 版中,这种不匹配将被忽略并在服务器上执行调用。

从 .NET Framework 1.1 版起,这种不匹配会引发以下异常:“System.Net.WebException: 基础连接已经关闭: 未能与远程服务器建立信任关系”。如果无法将远程处理客户端配置为使用证书公用名,可以在客户端应用程序配置文件中使用下列设置重写这种不匹配:

<system.net>
   <settings>
      <servicePointManager
         checkCertificateName="true"
      />
   </settings>
</system.net>

若要以编程方式将客户端设置为忽略证书名称不匹配,客户端必须创建实现 ICertificatePolicy 接口和 CheckValidationResult 的类实例才能在 certificateProblem 值为 0x800c010f 时返回 true。随后,您必须将该对象传递给 ServicePointManager.CertificatePolicy 属性,以便在 System.Net.ServicePointManager 对象中注册该对象。下面的代码是一个基本实现:

Public Class MyPolicy Implements ICertificatePolicy 
   Public Function CheckValidationResult(srvPoint As ServicePoint, certificate As X509Certificate, request As WebRequest, certificateProblem As Integer) As Boolean
      ' Check for policy common name mismatch. 
       If certificateProblem = 0 Or certificateProblem = &H800b010f Then
         Return True
      Else
         Return False
      EndIf
   End Function
End Class
public class MyPolicy : ICertificatePolicy {
   public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) {
      // Check for policy common name mismatch. 
      if (certificateProblem == 0 || certificateProblem == 0x800b010f)
         return true;
      else
         return false; 
   }
}

下面的代码在 System.Net ServicePointManager 中注册上述类的实例:

System.Net.ServicePointManager.CertificatePolicy = New MyPolicy()
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();

IIS 承载的远程处理应用程序中的身份验证

下表描述了在 Internet 信息服务 (IIS) 中承载服务时,可在 .NET 远程处理中实现某些类型的身份验证行为的配置设置。

所需的行为 配置设置 注释

服务器使用客户端默认凭据在每次调用时对客户端进行身份验证。

在服务器上,选中 IIS 中的“集成 Windows 身份验证”并清除“匿名访问”

在客户端上,将 useDefaultCredentials 设置为 true

这是 .NET Framework 1.0 版在 useDefaultCredentials 设置为 true 时的默认行为。

即使将 useAuthenticatedConnectionSharing 同时设置为 false,.NET Framework 1.1 版也支持此行为。

服务器使用客户端默认凭据对客户端进行一次身份验证;由此客户端发出的后续调用使用以前经过身份验证的连接。

在服务器上,选中 IIS 中的“集成 Windows 身份验证”并清除“匿名访问”

在客户端上,将“useDefaultCredentials”设置为 true

只有 .NET Framework 1.1 版或更高版本中才支持此行为。

服务器使用自定义或显式客户端凭据对客户端进行一次身份验证;由此客户端发出的后续调用使用以前经过身份验证的连接。

在服务器上,选中 IIS 中的“集成 Windows 身份验证”并清除“匿名访问”

在客户端上,将 credentials 设置为 ICredentials 实现,或者将 usernamepassworddomain 设置为显式值。无论采用何种设置,都必须同时将 unsafeAuthenticatedConnectionSharing 设置为 true 并提供仅映射到一位已经过身份验证的用户的 connectionGroupName 值。

只有 .NET Framework 1.1 版或更高版本中才支持此行为。

另请参见

参考

远程处理设置架构

概念

激活 URL
远程应用程序的配置
远程处理示例:在 Internet 信息服务 (IIS) 中承载