Wednesday, October 29, 2008

Interoperability Gotcha: SslContextToken Negotiation & WS-Policy

@YaronNaveh

When you try to import a WCF-created WSDL from a Java client such as Metro (WSIT) you may get the following error:



com.sun.xml.ws.security.impl.policy.Constants log_invalid_assertion
WARNING: SP0100: Policy assertion Assertion[com.sun.xml.ws.policy.sourcemodel.DefaultPolicyAssertionCreator$DefaultPolicyAssertion] {
  assertion data {
   namespace =   'http://schemas.microsoft.com/ws/2005/07/securitypolicy'
   prefix = 'mssp'
   local name = 'SslContextToken'
   value = 'null'
   optional = 'false'
   ignorable = 'false'
   attributes {
   name = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy:IncludeToken', value = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient'
}
}
  no parameters
  nested policy {
   namespace version = 'v1_5'
   id = 'null'
   name = 'null'
   vocabulary {
   1. entry =   'http://schemas.microsoft.com/ws/2005/07/securitypolicy:MustNotSendCancel'
   2. entry =   'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy:RequireDerivedKeys'
   }
   assertion set {
Assertion[com.sun.xml.ws.policy.sourcemodel.DefaultPolicyAssertionCreator$DefaultPolicyAssertion] {
  assertion data {
   namespace = 'http://schemas.microsoft.com/ws/2005/07/securitypolicy'
   prefix = 'mssp'
   local name = 'MustNotSendCancel'
   value = 'null'
   optional = 'false'
   ignorable = 'false'
   no attributes
  }
   no parameters
   no nested policy
   }
Assertion[com.sun.xml.ws.policy.sourcemodel.DefaultPolicyAssertionCreator$DefaultPolicyAssertion] {
   assertion data {
   namespace =   'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'
   prefix = 'sp'
   local name = 'RequireDerivedKeys'
   value = 'null'
   optional = 'false'
   ignorable = 'false'
   no attributes
   }
   no parameters
   no nested policy
   }
  }
}
} is not supported under Token assertion



The reason is that the WCF WS-Policy contains this section:



<mssp:SslContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient" xmlns:mssp="http://schemas.microsoft.com/ws/2005/07/securitypolicy">
<wsp:Policy>
...
</wsp:Policy>
</mssp:SslContextToken>


This means that your WCF service uses X.509 certificates negotiation. In such a scenario, clients use the server X.509 certificate for encryption. The unique here is that clients are not required to have this certificate out of band (as in most cases), rather they get this certificate using a SOAP-level negotiation. This is implemented as an extension over WS-Trust. While this is not strictly a proprietary Microsoft solution, Microsoft was the only one to implement it so far. In short - X.509 negotiation (SslContextToken) is not interoperable. Unfortunately(?) the default configuration of a WCF service is to use this negotiation. To turn it off either update your WsHttpBinding configuration:



   <message clientCredentialType="None" negotiateServiceCredential="false" />
</security>


Or choose the correct scenario in your CustomBinding:


<security authenticationMode="AnonymousForCertificate">
   <secureConversationBootstrap />
</security>

You can also use the equivalent cases for username authentication. Note that any clients (including WCF ones) will now need to have the service certificates defined out of band.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

3 comments:

Anonymous said...

Hi Yaron.

I'm new to web services and am trying to create a standalone axis client to connect to a WCF Service with sslcontexttoken assertion. I know its been a while you posted this, but could you offer me any tips on how to proceed?

Yaron Naveh (MVP) said...

hi

sslcontexttoken is not interoperable outside of wcf. Use regular x.509 tokens.

Bogard Coronel said...

Thanks for the post, very helpful.