How to: Create a Security Context Token for a Secure Session

By using a stateful security context token (SCT) in a secure session, the session can withstand the service being recycled. For instance, when a stateless SCT is used in a secure session and Internet Information Services (IIS) is reset, then the session data that is associated with the service is lost. This session data includes an SCT token cache. So, the next time a client sends the service a stateless SCT, an error is returned, because the key that is associated with the SCT cannot be retrieved. If, however, a stateful SCT is used, then the key that is associated with the SCT is contained within the SCT. Because the key is contained within the SCT and thus contained within the message, the secure session is not affected by the service being recycled. By default, Windows Communication Foundation (WCF) uses stateless SCTs in a secure session. This topic details how to use stateful SCTs in a secure session.

Note

Stateful SCTs cannot be used in a secure session that involves a contract that derives from IDuplexChannel.

Note

For applications that use stateful SCTs in a secure session, the thread identity for the service must be a user account that has an associated user profile. When the service is run under an account that does not have a user profile, such as Local Service, an exception may be thrown.

Note

When impersonation is required on Windows XP, use a secure session without a stateful SCT. When stateful SCTs are used with impersonation, an InvalidOperationException is thrown. For more information, see Unsupported Scenarios.

To use stateful SCTs in a secure session

  • Create a custom binding that specifies that SOAP messages are protected by a secure session that uses a stateful SCT.

    1. Define a custom binding, by adding a customBinding Element to the configuration file for the service.

      <customBinding>
      
    2. Add a <binding> child element to the customBinding Element.

      Specify a binding name by setting the name attribute to a unique name within the configuration file.

      <binding name="StatefulSCTSecureSession">
      
    3. Specify the authentication mode for messages sent to and from this service by adding a security element of customBinding child element to the customBinding Element.

      Specify that a secure session is used by setting the authenticationMode attribute to SecureConversation. Specify that stateful SCTs are used by setting the requireSecurityContextCancellation attribute to false.

      <security authenticationMode="SecureConversation"
                requireSecurityContextCancellation="false">
      
    4. Specify how the client is authenticated while the secure session is established by adding a secureConversationBootstrap element child element to the security element of customBinding.

      Specify how the client is authenticated by setting the authenticationMode attribute.

      <secureConversationBootstrap authenticationMode="UserNameForCertificate" />
      
    5. Specify the message encoding by adding an encoding element, such as textMessageEncoding element.

      <textMessageEncoding />
      
    6. Specify the transport by adding a transport element, such as the httpTransport element.

      <httpTransport />
      

    The following code example uses configuration to specify a custom binding that messages can use with stateful SCTs in a secure session.

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

Example

The following code example creates a custom binding that uses the MutualCertificate authentication mode to bootstrap a secure session.

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("https://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()
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("https://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();

When Windows authentication is used in combination with a stateful SCT, WCF does not populate the WindowsIdentity property with the actual caller's identity but instead sets the property to anonymous. Because WCF security must re-create the content of the service security context for every request from the incoming SCT, the server does not keep track of the security session in the memory. Because it is impossible to serialize the WindowsIdentity instance into the SCT, the WindowsIdentity property returns an anonymous identity.

The following configuration exhibits this behavior.

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

See Also

Other Resources

<custombinding>