Como: criar um token de contexto de segurança para uma sessão segura

Usando um token de contexto de segurança com estado (SCT) em uma sessão segura, a sessão pode resistir ao serviço que está sendo reciclado. Por exemplo, quando um SCT sem estado é usado em uma sessão segura e os Serviços de Informações da Internet (IIS) é redefinido, os dados de sessão associados ao serviço são perdidos. Esses dados de sessão incluem um cache de token SCT. Portanto, na próxima vez que um cliente enviar ao serviço um SCT sem estado, um erro será retornado, pois a chave associada ao SCT não poderá ser recuperada. No entanto, se um SCT com estado for usado, a chave associada ao SCT estará contida no SCT. Como a chave está contida no SCT e, portanto, contida na mensagem, a sessão segura não é afetada pelo serviço que está sendo reciclado. Por padrão, o Windows Communication Foundation (WCF) usa SCTs sem estado em uma sessão segura. Este tópico detalha como usar SCTs com estado em uma sessão segura.

Observação

SCTs com estado não podem ser usados em uma sessão segura que envolve um contrato que deriva de IDuplexChannel.

Observação

Para aplicativos que usam SCTs com estado em uma sessão segura, a identidade do thread para o serviço deve ser uma conta de usuário que tenha um perfil de usuário associado. Quando o serviço é executado em uma conta que não tem um perfil de usuário, como Local Service, uma exceção pode ser gerada.

Observação

Quando a representação for necessária no Windows XP, use uma sessão segura sem um SCT com estado. Quando SCTs com estado são usados com representação, um InvalidOperationException é gerado. Para obter mais informações, consulte Cenários sem suporte.

Para usar SCTs com estado em uma sessão segura

  • Crie uma associação personalizada que especifica que as mensagens SOAP são protegidas por uma sessão segura que usa um SCT com estado.

    1. Defina uma associação personalizada adicionando um <customBinding> ao arquivo de configuração do serviço.

      <customBinding>  
      </customBinding>
      
    2. Adicione um elemento filho de <associação> ao <customBinding>.

      Especifique um nome de associação definindo o atributo name como um nome exclusivo dentro do arquivo de configuração.

      <binding name="StatefulSCTSecureSession">  
      </binding>
      
    3. Especifique o modo de autenticação para mensagens enviadas de e para esse serviço adicionando um elemento filho de <segurança> ao <customBinding>.

      Especifique se uma sessão segura é usada definindo o atributo authenticationMode como SecureConversation. Especifique que os SCTs com estado são usados definindo o atributo requireSecurityContextCancellation como false.

      <security authenticationMode="SecureConversation"  
                requireSecurityContextCancellation="false">
      </security>
      
    4. Especifique como o cliente é autenticado enquanto a sessão segura é estabelecida adicionando um elemento filho <secureConversationBootstrap> à <segurança>.

      Especifique como o cliente é autenticado definindo o atributo authenticationMode.

      <secureConversationBootstrap authenticationMode="UserNameForCertificate" />  
      
    5. Especifique a codificação da mensagem adicionando um elemento de codificação, como <textMessageEncoding>.

      <textMessageEncoding />  
      
    6. Especifique o transporte adicionando um elemento de transporte, como o <httpTransport>.

      <httpTransport />  
      

    O exemplo de código a seguir usa a configuração para especificar uma associação personalizada que as mensagens podem usar com SCTs com estado em uma sessão segura.

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

Exemplo

O exemplo de código a seguir cria uma associação personalizada que usa o modo de autenticação MutualCertificate para inicializar uma sessão segura.

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 a autenticação do Windows é usada em combinação com um SCT com estado, o WCF não preenche a propriedade WindowsIdentity com a identidade do chamador real, mas define a propriedade como anônima. Como a segurança do WCF deve recriar o conteúdo do contexto de segurança do serviço para cada solicitação do SCT de entrada, o servidor não acompanha a sessão de segurança na memória. Como é impossível serializar a instância WindowsIdentity no SCT, a propriedade WindowsIdentity retorna uma identidade anônima.

A configuração a seguir exibe esse comportamento.

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

Confira também