WSE 3.0 - Kerberos, Secure Conversation and Stateful SCTs

I thought that I would publish some discussion threads on WSE issues that I have had recently that highlight some common questions. A recent discussion question was this;

Question: "I need advice with WSE 3.0 and implementing a web service that requires a Kerberos token. It seems that my simple web service and Windows client should be straight-forward but I’m not able to get past the error “Security requirements are not satisfied because the security header is not present in the incoming message. System.Exception {System.InvalidOperationException}

Here is the client policy file. The server one is nearly identical:

<policies xmlns="https://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="kerberosSecurity" type="Microsoft.Web.Services3.Design.KerberosAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="kerberos" type="Microsoft.Web.Services3.Design.KerberosTokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</extensions>
<policy name="KerberosClient">
<kerberosSecurity establishSecurityContext="true" renewExpiredSecurityContext="true" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="true" ttlInSeconds="300">
<token>
<kerberos targetPrincipal="host/MyServer" impersonationLevel="Impersonation" />
</token>
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
</protection>
</kerberosSecurity>
<requireActionHeader />
</policy>
</policies>"

Answer: It turns our that there are times when secure conversation and Kerberos can clash. When establishSecurityContext is set to true in the policy files (see above), then WSE 3.0 tries to acquire a Security Content Token (SCT) from the service to establish a secure conversation. The Request Security Context (RST) message sent from the client to acquire the SCT using the policy above uses a KerberosToken to protect the message so that only the service can decrypt the message. By default, WSE 3.0 generates stateful SCT’s (see Stateful Session section in this link) which means that the state of the SCT is carried with the SCT itself as a cookie value in the message. This state contains the server's KerberosToken inside of it, which you can see by looking for the <cookie> element in the SCT.

Since Kerberos Tokens can *only* ever be used once, using this stateful SCT doesn’t work. This is because every time the client makes a request to the service, it protects the message with that SCT, which carries the state with it. But because this state has a "use once" KerberosToken, the request fails at the server.

There are two options to work around this:
1)       Don’t use SCT’s at all and hence do not use Secure Conversation. You can do this by setting establishSecurityContext to false in the policy file at both the client and the service.
2)       Use SCT’s (i.e. establishSecurityContext set to true) but turn off stateful SCT by setting statefulSecurityContextToken to false inside <microsoft.web.services3> of web.config. e.g.

      <tokenIssuer>

          <statefulSecurityContextToken enabled="false" />

      </tokenIssuer>

 

       This can also be done on the Message tab in the WSE Configuration Settings available from the VS2005 Solution Explorer context menu.

1) Has the disadvantage of not taking advantage of the performance improvement of using secure conversation when the number of messages is >2. However you may only send a single message and therefore not require secure conversation, which is fine.

2) Is a better option as it still allow secure conversation (where messages are >2) and works because the SCT state is no carried with the message and simply cached on the server side. The one difference is that you can no longer use secure conversation in web farms, but you can still use Kerberos on web farms at a slight performance decrease. If you really need the performance improvement in a web farm scenario using Kerberos Token using  secure conversation, then you need to maintain your own state on the server i.e. implement your own SCT cache using something like a SQL database as described in Managing Security Context Tokens in a Web Farm.

I will post more common discussion threads like this over the next few months. It is also worth sending questions to the Web Services Forum which we monitor on a regular basis