Hosting Remote Objects in Internet Information Services (IIS)

When you use Internet Information Services (IIS) to host your remote type, you cannot programmatically configure the remoting system for your remotable type directly in the host process, because the host application domains are created by IIS and ASP.NET. However, you can use the Global.asax file to do much of the same programmatic configuration that you can do in other types of application domains. To use a configuration file to configure remoting when IIS is your host process, you must 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).

In addition, you cannot do any of the following:

  • Specify an application name when hosting in IIS. The name of the virtual directory becomes your application name.
  • Use the <debug> element in a Web.config file that is used for .NET remoting configuration.
  • Use 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 configuration file for remoting will still contain the basic information about your type that the system needs to 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 load, the remoting configuration will cause that new application domain to try to listen on the same port again, raising an exception. For example, a simple Web.config file for an IIS-hosted .NET remoting XML Web service might look like the following code example. Remember, there is no need to include the channel configuration lines in this case, except to attach the channel properties (in this case, the priority property) to the instance used.

<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 will automatically be 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:

http://<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:

http://<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.

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
[C#]
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);
} 

In other words, you can host the service in IIS the same way you would in other types of host application domains. 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 will be 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 method 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(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, Integer certificateProblem) As Boolean
      ' Check for policy common name mismatch. 
       If certificationProblem = 0 Or certificateProblem = &H800c010f Then
         Return True
      Else
         Return False
   End Function
End Class
[C#]
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 == 0x800c010f)
         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()
[C#]
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 client's default credentials. On the server, select Integrated Windows Authentication and clear Anonymous access in IIS.

On the client, set the credentials to use CredentialCache.DefaultCredentials.

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

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

The server authenticates the client once using the client's 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 the .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 the .NET Framework version 1.1 or later.

See Also

Activation URLs | Configuration | Remoting Settings Schema | Remoting Example: Hosting in Internet Information Services (IIS)