Improve the performance of your services with Secure conversation

Secure Conversation is a feature designed to improve the performance of an application that needs to interchange more than one messages with a service.

When SC is enabled, the token negotiation and authentication happens once compared to other tokens where that negotiation is done for each request to the service.

In the first negotiation, the client sends a "RequestSecurityToken" message to the service in order to ask for a session token. That message is part of the WS-Trust specification and it is protected (encrypted and signed) with a security token that will be the base token for the session token.

After that, the service creates a new token called Secure context token (SCT), which contains a reference to the original token and a symmetric key to perform cryptographic operations like encrypt or sign messages. (Message confidentiality and integrity).

WSE and WCF, both implement this feature and the service itself is responsible to emit the SCT. Therefore, the service is also a "Security token service" or STS.

The service returns the SCT to the client application and keeps the state of the original token using different strategies (Cookies, in-memory stores, etc). This article  in the MSDN describes very well what are the different approaches that a STS can use to maintain the state of a session.

The most import benefits of using a SCT to protect the communication between a client and service are:

 

1. The service execution is three or four times faster than the same execution with other tokens.

2. It is valid for a short time but it can be automatically renewed. As consequence, the  client application does not need to keep the original token.

   This is really important when the original token contains some sensitive information such an user name or password. (Username Token).

 

Secure conversation in WSE

 

Activating SC in WSE is really easy, it is just a flag in the policy configuration. All the policies for the turn-key scenarios support two attributes, "establishSecurityContext" to turn on the SC feature and renewExpiredSecurityContext to automatically renew the SCT when it expires (This attribute is helpful when storing the original token in the client is not a feasible solution).

 

The sample below shows how to activate SC for a "MutualCertificate" turn-key scenario:

 

<mutualCertificate10Security establishSecurityContext="true" renewExpiredSecurityContext="true">

  <serviceToken>

    <x509 storeLocation="LocalMachine" storeName="My" findValue="CN=WSE2QuickStartServer" findType="FindBySubjectDistinguishedName" />

  </serviceToken>

  <protection>

    <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

    <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />

    <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />

  </protection>

</mutualCertificate10Security>

 

WSE supports two modes to mantain the state of the original security token for a particular session.

  • Cookie mode, where the state is stored in a temporary cookie. This mode was designed to support web farm scenarios.
  • In-Memory cache in the STS

 

<microsoft.web.services3>

  <tokenIssuer>

    <statefulSecurityContextToken enabled="false" />

  </tokenIssuer>

</microsoft.web.services3>

 

The default value for this setting is "true", which enables the Cookie mode. The state for a kerberos token can not be maintained in a cookie and therefore it is the only turn-key scenario that doesn't support stateful SCT.

 

The code below shows how to reuse a SCT from a client application.

 

HelloWorldServiceWse serviceProxy = new HelloWorldServiceWse();

UsernameToken usernameToken = new UsernameToken("user", "password");

serviceProxy.SetClientCredential(usernameToken);

serviceProxy.SetPolicy("ClientPolicy");

serviceProxy.HelloWorld();

SecureConversationCorrelationState correlationState = serviceProxy.ResponseSoapContext.SessionState.Get<SecureConversationCorrelationState>("");

if (correlationState != null)

{

    SecurityContextToken sct = correlationState.Token as SecurityContextToken;

    if (sct != null)

    {

        serviceProxy = new HelloWorldServiceWse();

        serviceProxy.SetClientCredential(sct);

        // Set the ClientPolicy onto the proxy

        serviceProxy.SetPolicy("ClientPolicy");

        serviceProxy.HelloWorld();

        sct.Cancel();

    }

}

 
   

Secure conversation in WCF

 

WCF turn on SC by default for all binding that support WS-Security (WsHttpBinding, NetTcpBinding, netMsmqBinding).

The Custom binding also offers the possibility to enable SC depending on the value of the attribute "authenticationMode" (The value for this attribute must be "SecureConversation"). In addition, you can configure a binding that will be used to establish a communication with the STS by means of the element "secureConversationBootstrap".

WCF is completely different from WSE since it hides the SCT from the client application and automatically maintains a copy of this token at channel level (A channel is related to a contract). That is, it will reuse the SCT as long as the client application uses the same instance of the client channel.

When the channel is closed in a normal fashion, a message is sent to the service to release the SCT.  If the channel closes abruptly, the SCT will eventually be released on the service after after a period of in-actively.

 

The configuration below shows two equivalent bindings that use the SC feature:

 

<bindings>

  <wsHttpBinding>

    <binding name="ServiceBinding">

      <security mode="Message">

        <message clientCredentialType="Certificate" establishSecurityContext="true"/>

      </security>

    </binding>

  </wsHttpBinding>

  <customBinding>

    <binding name="ServiceBinding">

      <security authenticationMode="SecureConversation"

            requireSecurityContextCancellation ="false">

         <secureConversationBootstrap authenticationMode="MutualCertificate">

         </secureConversationBootstrap>

      </security>

      <httpTransport/>

    </binding>

   </customBinding>

</bindings>

 

The "requireSecurityContextCancellation" attribute specifies if the client application must send a "shutdown" message to the service after closing the client channel.

9 Comments

  • I read comments from you on other sites saying all the assertions support SecureConversation. But I think UserNameOverTransport does not support SecureCOnversation. So can one implement session mgmt and single sign on feature when we do not want to use certificates and want the user to logw with username and password?

  • Hi, I think I was not clear on what I said. SecureConversation only works when you use Message Security, since it uses a STS infrastructure. You can probably use SAML, take a look to the SAML implementation for WSE.

    Pablo.

  • I looked at the sample implementation of SAML and WSE 3.0, but why are all of them using userNameOverCertificate policy.

    1 We want to host web services over TCP using WSE 3.0.
    2 And want clients to authenticate b4 calling web services. BUt dont want client to pass in credentials every time, so would need some sort of security token mgmt i guess. We do not want to install certificates for sure.
    3 Also certain features are available only to certain roles like admin, so we need authorization.
    4 And we need to maintain session on server so we can keep certain values in session cache for currently logged in user.

    I thought this is a very generic problem that everyone would be facing.

    I have searching a lot to find how can we achieve this. Do u have any ideas? Will we have to custom code everything?

  • I tried out the code above to reuse a SCT from a client application, but it fails on the second call to HelloWorld. I think this is because the client policy is expecting a UserName token as the credential, but an SCT is supplied.
    Can you get this to work by using a second client policy somehow?

  • Do you know if a VeriSign or GeoTrust ssl certificate is adequate for digitally signing soap messages as well as setting up a secure connection between server and client(s)?

  • Hi Diane,

    The GeoTrust ssl certificate works perfect for digital signatures and data encryption. I am not completely sure about the verisign certificates.

    Thanks
    Pablo.

  • Hi Cibrax

    I'm currently using WCF with the netTcpBinding, and have the standard security mode on "transport". If I change this to "message", will it give me a better performance? (or should I perform extra actions to implement this?)

    regards, Jowen

  • The solution you use for reusing the SCT token is not really good (in my situation). I subscribe to various event handlers on the service proxy (*Completed handlers for async), and doing a "new ServiceClient" makes these handlers obsolete.

  • hi cibrax, i read your post and it was very useful. I made all changes to enable SecureConversation in my WebService. BUT!
    I have a problem in the first access to the WS. First time run delays about 10 seconds (wich is not accepted by invoker who wait just for 10 seconds).
    My WebService's AppPool is configured to recycle worker processes daily at 1:00am, the normal operation of WebService starts at 9:00am, and first time invoked is ALWAYS rejected (by taking more than 10 seconds). I enable WSE trace to determine that behavior.

    Have you any ideas on how to troubleshoot this problem?

    I'm in IIS6 on Win2K3 Server using WSE 2.0 SP2.

    Thanks in advance.

Comments have been disabled for this content.