Procedura: creare un token di contesto di sicurezza per una sessione sicura

Per evitare la perdita di una determinata sessione protetta quando il servizio viene riciclato, è possibile utilizzare in tale sessione un token di contesto di sicurezza (SCT, Security Context Token) con stato. Ad esempio, quando in una sessione protetta si utilizza un token SCT senza stato e si reimposta Internet Information Services (IIS), i dati di sessione associati al servizio vengono persi. Questi dati di sessione comprendono una cache del token SCT. Pertanto, quando un client invia al servizio un token SCT senza stato, viene restituito un errore, in quanto risulta impossibile recuperare la chiave associata al token SCT. Se tuttavia si utilizza un token SCT con stato, la relativa chiave associata è contenuta nel token SCT e quindi nel messaggio. Ne consegue che in questo caso il riciclo del servizio non influisce sulla sessione protetta. Per impostazione predefinita, Windows Communication Foundation (WCF) usa le unità di sicurezza senza stato in una sessione protetta. In questo argomento viene descritto in modo dettagliato come utilizzare token SCT con stato in una sessione protetta.

Nota

I token SCT con stato non possono essere utilizzati in una sessione protetta che prevede un contratto derivato dall'interfaccia IDuplexChannel.

Nota

Nelle applicazioni che utilizzano token SCT con stato in una sessione protetta, l'ID del thread del servizio deve essere un account utente a cui è stato associato un profilo utente. Quando il servizio viene eseguito nel contesto di un account privo di profilo utente, ad esempio Local Service, è possibile che venga generata un'eccezione.

Nota

Quando la rappresentazione è obbligatoria in Windows XP, utilizzare una sessione protetta priva di token SCT con stato. Infatti, quando i token SCT con stato vengono utilizzati con la rappresentazione, il sistema genera un'eccezione InvalidOperationException. Per altre informazioni, vedere Scenari non supportati.

Per utilizzare token SCT con stato in una sessione protetta

  • Creare un'associazione personalizzata che prevede la protezione dei messaggi SOAP mediante una sessione protetta che utilizza un token SCT con stato.

    1. Definire un binding personalizzato aggiungendo un elemento <customBinding> al file di configurazione per il servizio.

      <customBinding>  
      </customBinding>
      
    2. Aggiungere un elemento figlio <binding> a <customBinding>.

      Specificare il nome dell'associazione impostando l'attributo name su un nome univoco all'interno del file di configurazione.

      <binding name="StatefulSCTSecureSession">  
      </binding>
      
    3. Specificare la modalità di autenticazione dei messaggi scambiati con il servizio aggiungendo un elemento figlio <security> a <customBinding>.

      Specificare l'utilizzo di una sessione protetta impostando l'attributo authenticationMode su SecureConversation. Specificare l'utilizzo di token SCT con stato impostando l'attributo requireSecurityContextCancellation su false.

      <security authenticationMode="SecureConversation"  
                requireSecurityContextCancellation="false">
      </security>
      
    4. Specificare il modo in cui il client viene autenticato mentre viene stabilita la sessione protetta aggiungendo un elemento figlio <secureConversationBootstrap> all'elemento <security>.

      Specificare la modalità di autenticazione del client impostando l'attributo authenticationMode.

      <secureConversationBootstrap authenticationMode="UserNameForCertificate" />  
      
    5. Specificare la codifica dei messaggi aggiungendo un elemento di codifica, ad esempio <textMessageEncoding>.

      <textMessageEncoding />  
      
    6. Specificare il trasporto aggiungendo un elemento di trasporto, ad esempio <httpTransport>.

      <httpTransport />  
      

    Nell'esempio di codice seguente si utilizza la configurazione per specificare un'associazione personalizzata in cui i messaggi possono utilizzare token SCT con stato in una sessione protetta.

    <customBinding>  
      <binding name="StatefulSCTSecureSession">  
        <security authenticationMode="SecureConversation"  
                  requireSecurityContextCancellation="false">  
          <secureConversationBootstrap authenticationMode="UserNameForCertificate" />  
        </security>  
        <textMessageEncoding />  
        <httpTransport />  
      </binding>  
    </customBinding>  
    

Esempio

Nell'esempio di codice seguente viene creata un'associazione personalizzata che usa la modalità di autenticazione MutualCertificate per l'avvio automatico di una sessione protetta.

SecurityBindingElement security = SecurityBindingElement.CreateMutualCertificateBindingElement();

// Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, false);

// Specify whether derived keys are needed.
security.SetKeyDerivation(true);

// Create the custom binding.
CustomBinding myBinding = new CustomBinding(security, new HttpTransportBindingElement());

// Create the Type instances for later use and the Uri for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
    Uri("http://localhost:8036/serviceModelSamples/");

// Create the ServiceHost and add an endpoint, then start
// the service.
ServiceHost myServiceHost =
    new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
    (contractType, myBinding, "secureCalculator");
myServiceHost.Open();
Dim security As SecurityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement()


' Use a secure session and specify that stateful SecurityContextToken security tokens are used.
security = SecurityBindingElement.CreateSecureConversationBindingElement(security, False)

' Specify whether derived keys are needed.      
security.SetKeyDerivation(True)

' Create the custom binding.
Dim myBinding As New CustomBinding(security, New HttpTransportBindingElement())

' Create the Type instances for later use and the Uri for 
' the base address.
Dim contractType As Type = GetType(ICalculator)
Dim serviceType As Type = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8036/serviceModelSamples/")

' Create the ServiceHost and add an endpoint, then start
' the service.
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")
myServiceHost.Open()

Quando si usa l'autenticazione di Windows insieme ai token SCT con stato, WCF imposta la proprietà WindowsIdentity su anonimo anziché popolarla con l'ID del chiamante effettivo. Poiché il sistema di sicurezza di WCF deve ricreare il contenuto del contesto di sicurezza del servizio per ogni richiesta contenuta nel token SCT in ingresso, il server non memorizza alcuna traccia relativa alla sessione di sicurezza. Inoltre, poiché è impossibile serializzare l'istanza della classe WindowsIdentity nel token SCT, la proprietà WindowsIdentity restituisce un'identità anonima.

Questo comportamento viene illustrato nella configurazione seguente.

<customBinding>  
  <binding name="Cancellation">  
       <textMessageEncoding />  
        <security
            requireSecurityContextCancellation="false">  
              <secureConversationBootstrap />  
        </security>  
    <httpTransport />  
  </binding>  
</customBinding>  

Vedi anche