Hosting Remote Objects in Internet Information Services (IIS)

This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the  Windows Communication Foundation (WCF).

To host a remote object in Internet Information Services (IIS) you must configure the remote object. Normally this is done either within a configuration file or programmatically within the hosting application code. When a remote object is hosted within IIS you can either place the configuration information a Web.config file or you can programmatically configure the remote object in the Application_Start method in the Global.asax file.

To use a configuration file to configure a remote object, do the following:

  • Place your configuration information in the Web.config file in the IIS virtual directory that you have chosen to use.

  • Place your remotable type implementation in the \bin directory (or use the Global Assembly Cache tool (Gacutil.exe) to place it in the global assembly cache).

When specifying a Web.config file, the following are not supported:

  • Specifying an application name, the name of the virtual directory becomes your application name.

  • Using the <debug> element in a Web.config file that is used for .NET remoting configuration.

  • Using any channel other than the HttpChannel.

  • Use the Web.config file and the <client> element to configure your client Web application automatically. If you want to use IIS as a remoting client, you must call RemotingConfiguration.Configure in the Application_Start method in the Global.asax file.

The Web.config file still contains the basic information about your type that the system must know, but some declarations must change slightly to accommodate the hosting environment. For example, you can custom configure a particular HttpChannel, but you should not specify a port for the channel; should ASP.NET create another application domain to handle the load, the remoting configuration causes that new application domain to try to listen on the same port again, raising an exception. For example, a Web.config file for an IIS-hosted .NET remote object might look like the following code example. It is not necessary to include the channel configuration lines in this case, except to set the channel properties (in this case, the priority property).

<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>

Note

Do not specify a port for any channels listed here. If you want your application to listen on a particular port, use Internet Services Manager to specify that IIS listen on that port. The channel you configure is automatically used to handle remote requests submitted on that port.

To successfully host server-activated (that is, <wellknown>) objects inside IIS, you must have an object Uniform Resource Identifier (URI) that ends in .rem or .soap. There is no such requirement for other host application domains. To use the Soapsuds tool (Soapsuds.exe) to generate metadata for a server-activated object hosted in IIS, the URL to pass as an argument to Soapsuds.exe is as follows:

https://< Computer >:< Port >/< VirtDir >/< ObjectURI >?wsdl

For client-activated objects hosted in IIS or any other application domain, you do not need an object URI of any form. The URL to pass as an argument to Soapsuds.exe is as follows:

https://< Computer >:< Port >/< VirtDir >/RemoteApplicationMetadata.rem?wsdl

Programmatic configuration in IIS is done using the Global.asax page. The following example shows the same configuration as the previously shown configuration file, but uses the Global.asax file.

<%@ 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);
} 

The following entries must be placed in the Web.config file to make sure the required assemblies are referenced:

<?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>

For a complete example, see Remoting Example: Hosting in Internet Information Services (IIS).

Using SSL Certificates with .NET Remoting

Certificates identify a particular computer, the name of which resides in the common name of the certificate. However, it is easy to change the name of a computer or use "localhost" in client configuration files, which creates a mismatch between the client and the common name in the server certificate. In the .NET Framework version 1.0, this mismatch is ignored and the call is invoked on the server.

Starting with .NET Framework version 1.1, this mismatch throws the following exception: "System.Net.WebException: The underlying connection was closed: Could not establish trust relationship with remote server." If you are unable to configure the remoting client to use the certificate common name, you can override the mismatch using the following settings in your client application configuration file:

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

To make your client overlook the certificate name mismatch programmatically, the client must create an instance of a class that implements the ICertificatePolicy interface and implements the CheckValidationResult to return true if the certificateProblem value is 0x800c010f. You must then register the object with the System.Net.ServicePointManager object by passing the object to the ServicePointManager.CertificatePolicy property. The following code is a basic implementation:

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; 
   }
}

The following code registers an instance of the preceding class with the System.Net ServicePointManager:

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

Authentication in IIS-hosted Remoting Applications

The following table describes the configuration settings that enable certain types of authentication behavior in .NET remoting when hosting your service in Internet Information Services (IIS).

Desired behavior Configuration settings Comments

The server authenticates the client on each call using the clients default credentials.

On the server, select Integrated Windows Authentication and clear Anonymous access in IIS.

On the client, set useDefaultCredentials to true.

This is the default behavior in version 1.0 of.NET Framework when useDefaultCredentials is true.

This behavior is supported in version 1.1 of.NET Framework if useAuthenticatedConnectionSharing is also set to false.

The server authenticates the client once using the clients default credentials; subsequent calls from this client use the previously authenticated connection.

On the server, select Integrated Windows Authentication and clear Anonymous access in IIS.

On the client, set useDefaultCredentials to true.

This behavior is supported only in.NET Framework version 1.1 or later.

The server authenticates the client once using custom or explicit client credentials; subsequent calls from this client use the previously authenticated connection.

On the server, select Integrated Windows Authentication and clear Anonymous access in IIS.

On the client, either set the credentials to an ICredentials implementation, or set the username, password, and domain to explicit values. In either case, you must also set unsafeAuthenticatedConnectionSharing to true and provide a connectionGroupName value that maps to only one authenticated user.

This behavior is supported only in.NET Framework version 1.1 or later.

See Also

Reference

Remoting Settings Schema

Concepts

Activation URLs
Configuration of Remote Applications
Remoting Example: Hosting in Internet Information Services (IIS)