Esempio di comunicazione remota: hosting in Internet Information Services (IIS)

Nell'esempio riportato di seguito viene implementato un servizio Web di base con alcune complicazioni. BinaryFormatter viene utilizzato perché il flusso serializzato è più compatto e occorre meno tempo per serializzare e deserializzare il flusso. Inoltre, se in Internet Information Services (IIS) è attiva l'Autenticazione integrata Windows, anche nota come autenticazione NTLM, il server autentica il client e quindi restituisce al client l'identità autenticata con IIS. Infine, è possibile proteggere il servizio Web modificando l'URL nel file di configurazione del client per utilizzare https come schema di protocollo e configurando IIS per richiedere la crittografia SSL (Secure Sockets Layer) per la directory virtuale. Nell'esempio questo processo non viene illustrato.

Attenzione   .NET Remoting non consente di effettuare l'autenticazione né la crittografia per impostazione predefinita. Si consiglia dunque di eseguire tutte le azioni necessarie per verificare l'identità dei client o dei server prima di interagire con essi in modalità remota. Poiché l'esecuzione delle applicazioni .NET Remoting richiede autorizzazioni FullTrust, qualora a un client non autorizzato venisse concesso l'accesso al server, il client potrebbe eseguire codice come se fosse completamente attendibile. È necessario autenticare sempre gli endpoint e crittografare i flussi di comunicazione mediante l'hosting dei tipi remoti in IIS oppure generando a questo scopo una coppia di sink di canale personalizzata.

Per compilare ed eseguire l'esempio

  1. Salvare tutti i file in una directory denominata RemoteIIS.

  2. Compilare l'intero esempio digitando i seguenti comandi al prompt dei comandi:

    csc /noconfig /t:library /r:System.Web.dll /out:ServiceClass.dll ServiceClass.cs

    csc /noconfig /r:System.Runtime.Remoting.dll /r:System.dll /r:ServiceClass.dll Client.cs

  3. Creare una sottodirectory \bin e copiarvi il file ServiceClass.dll.

  4. Creare una directory virtuale in IIS. Creare l'alias "HttpBinary" per tale directory, quindi impostare "RemoteIIS" come directory di origine.

  5. Impostare il metodo di autenticazione per la directory virtuale su Autenticazione integrata di Windows (in precedenza, autenticazione NTLM).

  6. Assicurarsi che IIS sia avviato e digitare client al prompt dei comandi nella directory "RemoteIIS".

Questa applicazione viene eseguita su un singolo computer o in una rete. Per eseguire l'applicazione in una rete, nella configurazione del client è necessario sostituire hostlocale con il nome del computer remoto.

ServiceClass.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;

public interface IService{

   DateTime GetServerTime();
   string GetServerString();

}

// IService exists to demonstrate the possibility of publishing only the interface.
public class ServiceClass : MarshalByRefObject, IService{

   private int InstanceHash;

   public ServiceClass(){
      InstanceHash = this.GetHashCode();
   }

   public DateTime GetServerTime(){
      return DateTime.Now;
   }

   public string GetServerString(){
      // Use the HttpContext to acquire what IIS thinks the client's identity is.
      string temp = HttpContext.Current.User.Identity.Name;
      if (temp == null || temp.Equals(string.Empty))
         temp = "**unavailable**";
      return "Hi there. You are being served by instance number: " 
         + InstanceHash.ToString() 
         + ". Your alias is: " 
         + temp;
   }
}

Web.config

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="SingleCall" objectUri="SAService.rem"
               type="ServiceClass, ServiceClass"/>
         </service>
         <channels>
            <channel ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

Client.cs

using System;
using System.Collections;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;

public class Client{

   public static void Main(string[] Args){

         // Tells the system about the remote object and customizes the HttpChannel
         // to use the binary formatter (which understands that base64 encoding is needed).
         RemotingConfiguration.Configure("Client.exe.config");

         // New proxy for the ServiceClass.
         // If you publish only the IService interface, you must use Activator.GetObject.
         ServiceClass service = new ServiceClass(); 
            
         // Programmatically customizes the properties given to the channel. This sample uses the
         // application configuration file.
         // IDictionary Props = ChannelServices.GetChannelSinkProperties(service);
         // Props["credentials"] = CredentialCache.DefaultCredentials;

         // Reports the client identity name.
         Console.WriteLine("ConsoleIdentity: " + WindowsIdentity.GetCurrent().Name);

         // Writes what the server returned.
         Console.WriteLine("The server says : " + service.GetServerString());
         Console.WriteLine("Server time is: " + service.GetServerTime());      
   }
}

Client.exe.config

<configuration>
   <system.runtime.remoting>
      <application>
         <channels>
            <channel ref="http" useDefaultCredentials="true" port="0">
               <clientProviders>
                  <formatter 
                     ref="binary"
                  />
               </clientProviders>
            </channel>
         </channels>
         <client>
            <wellknown 
               url="https://localhost:80/HttpBinary/SAService.rem"
               type="ServiceClass, ServiceClass"
            />
         </client>
      </application>
   </system.runtime.remoting>
</configuration>

Vedere anche

Esempi di comunicazione remota | Configurazione | Hosting di oggetti remoti in Internet Information Services (IIS)