I'm trying to add WS-Security to an existing service I have, where said service is accessed over TLS, and I've mostly succeeded in testing it with SoapUI.
However I'm having a problem with the response coming back; even though the response looks complete, SoapUI reports:
ERROR:org.apache.ws.security.WSSecurityException: An invalid security token was provided (Bad TokenType "")
org.apache.ws.security.WSSecurityException: An invalid security token was provided (Bad TokenType "")
at org.apache.ws.security.str.BSPEnforcer.checkEncryptedKeyBSPCompliance(BSPEnforcer.java:113)
at org.apache.ws.security.str.SecurityTokenRefSTRParser.processPreviousResult(SecurityTokenRefSTRParser.java:313)
at org.apache.ws.security.str.SecurityTokenRefSTRParser.parseSecurityTokenReference(SecurityTokenRefSTRParser.java:101)
at org.apache.ws.security.processor.ReferenceListProcessor.decryptDataRefEmbedded(ReferenceListProcessor.java:169)
at org.apache.ws.security.processor.ReferenceListProcessor.handleReferenceList(ReferenceListProcessor.java:104)
at org.apache.ws.security.processor.ReferenceListProcessor.handleToken(ReferenceListProcessor.java:64)
at org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:402)
From what I'm reading, this is due to a missing TokenType attribute on the SecurityTokenReference element in the reply, and this is a condition of complying with the Basic Security Profile.
The question is - how do I get this attribute populated in WCF? I've not found any clear information on this.
The encrypted key section in the SOAP response from the WCF service looks like this:
<e:EncryptedKey Id="_0" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns="http://www.w3.org/2000/09/xmldsig#"/>
</e:EncryptionMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">K6Ag94AG3hQuQ+rqQcBvb88Vl+Y=</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>FQ58hAfisez2D8J9A49xFRQjfTSFhrWP9wJDnWq0MctAyLhoAynzu3/Z0jYK91uE4DVCgkFo9QGH6O/kR1icQxkpv/xb5gcB1mJTbIpbCOzw6ZtMEfbY0r9ML2fDcChGFPM/nh70Daqi4P9IO8dIZ5EAUcERvDMFvj4fhwwVycSNFUX40/8ywQALQksPb+1j2B3pzHntcyb6CJ0qD10xjbyyQoT0BgR/HeDQEJDQNvx41eqoDSy2/ImkNNfFCXQ47/k1sN48tWur6GEzDuwUBbiAJxVrCgzc6a7F9CrhWiE6DAublBzM8/EBKP5UD5p2WTcjDQxI4cBhqRwIGYcfhQ==</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
My WCF bindings look like this:
<customBinding>
<binding name="NewBinding0">
<security
authenticationMode="MutualCertificate"
allowSerializedSigningTokenOnReply="true"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
securityHeaderLayout="Lax"
requireSignatureConfirmation="false"
messageProtectionOrder="EncryptBeforeSign"
includeTimestamp="false"
>
<localServiceSettings detectReplays="false" />
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>
As an afterthought, is BSP strictly required to be a "good" message? I can't see any way to switch BSP checking off in SoapUI, but given WCF doesn't apply it I assume it is acceptable? Ultimately, consumers of the service may be Java, may be .NET, may be something else, so I'm happy to drop BSP support in the name of wider compatibility if BSP can be disabled. If this does seem an acceptable path, then rather than .NET attempting to conform to BSP, how do I switch BSP processing off in SoapUI for testing? (That said, if enabling BSP in .NET is straight forward by tweaking the binding, I'm happy to persue that).