I have created a mock service based on a WSDL from a vendor that is already in
use.
One of the calls requires that the message be timestamped/signed/encrypted
before transmission.
The real service provider issued an X.509 certificate for our use. I have had
our internal folks issue one like it with the same extensions.
Everything is in place, but when the client app hits my mock service, it gets
an error that is neither clear or helpful:
org.apache.cxf.binding.soap.SoapFault: A security error was encountered when
verifying the message
...
Caused by: org.apache.wss4j.common.ext.WSSecurityException: An error was
discovered processing the <wsse:Security> header
Digging into the CXF trace log, I barely managed to find these:
2017-11-02 19:49:52.018 DEBUG
[org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor] WSS4JInInterceptor: enter
handleMessage()
2017-11-02 19:49:54.037 WARN
[org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor] Security processing
failed (actions mismatch)
The messages are being generated by CXF (wsdl2java situation).
The WSDL policy section is thus:
<wsp:Policy wsu:Id="wsHttpEndPoint_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
>
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken
RequireClientCertificate="false" />
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256 />
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp />
</wsp:Policy>
</sp:TransportBinding>
<sp:EndorsingSupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
>
<wsp:Policy>
<sp:SecureConversationToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"
>
<wsp:Policy>
<sp:BootstrapPolicy>
<wsp:Policy>
<sp:SignedParts>
<sp:Body />
<sp:Header
Name="To"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="From"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="FaultTo"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="ReplyTo"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="MessageID"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="RelatesTo"
Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header
Name="Action"
Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body />
</sp:EncryptedParts>
<sp:TransportBinding>
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken
RequireClientCertificate="false" />
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256 />
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp />
</wsp:Policy>
</sp:TransportBinding>
<sp:EndorsingSupportingTokens>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"
>
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
</sp:X509Token>
<sp:SignedParts>
<sp:Header
Name="To"
Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
</wsp:Policy>
</sp:EndorsingSupportingTokens>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefThumbprint />
</wsp:Policy>
</sp:Wss11>
<sp:Trust10>
<wsp:Policy>
<sp:MustSupportIssuedTokens />
<sp:RequireClientEntropy />
<sp:RequireServerEntropy />
</wsp:Policy>
</sp:Trust10>
</wsp:Policy>
</sp:BootstrapPolicy>
</wsp:Policy>
</sp:SecureConversationToken>
</wsp:Policy>
</sp:EndorsingSupportingTokens>
<sp:Wss11
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy />
</sp:Wss11>
<sp:Trust10
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
>
<wsp:Policy>
<sp:MustSupportIssuedTokens />
<sp:RequireClientEntropy />
<sp:RequireServerEntropy />
</wsp:Policy>
</sp:Trust10>
<wsaw:UsingAddressing />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
and a message being sent to my mock service looks like:
ID: 1
Address: https://localhost:8443/mock-vls-ws/services/mockAuthenticationService
Encoding: UTF-8
Http-Method: POST
Content-Type: application/soap+xml;
action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT"; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive],
content-type=[application/soap+xml;
action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT"; charset=UTF-8],
host=[localhost:8443], pragma=[no-cache], transfer-encoding=[chunked],
user-agent=[Apache-CXF/3.1.10]}
Payload:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<Action
xmlns="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</Action>
<MessageID
xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:d4a37685-340a-41e3-9ad5-33d21601b2b2</MessageID>
<To xmlns="http://www.w3.org/2005/08/addressing"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="_7f09a81a-706a-4d03-932e-c402c7af8d16"
>https://localhost:8443/mock-vls-ws/services/mockAuthenticationService</To>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
soap:mustUnderstand="true"
>
<wsse:BinarySecurityToken
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="X509-fbd22553-2805-4f67-af0c-cd552b6c4ea1"
>MIIHPzCCBSegAwIBAgITRAAAc2IaBbGCTk7sGwAAAABzYjANBgkqhkiG9w0BAQsFADBBMRMwEQYKCZImiZPyLGQBGRYDRFBTMRMwEQYKCZImiZPyLGQBGRYDVExFMRUwEwYDVQQDEwxEUFNJc3N1ZUNBMDEwHhcNMTcxMTAxMTczMTUzWhcNMjAxMDMxMTczMTUzWjCBjTELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xKjAoBgNVBAoTIVRleGFzIERlcGFydG1lbnQgb2YgUHVibGljIFNhZmV0eTELMAkGA1UECxMCSVQxJDAiBgNVBAMMG2Rwcy5kZXZlbG9wZXJAZHBzLnRleGFzLmdvdjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIPrRFbLW92EYqeCr/jrEkFaHLP4Zm8lMnpNV1aJtEPuZno3GdBtRNadTHpg+x6dKQemTgrpZJIzBCsm6iCWliB2PWqdFbQKt3DQoG4o8fT8DxPNZLod9Y/Rfi8Lb7NO33WdFu6JG8KRypTs1mQUItQ03TbKapACMmyoXhctZEgnSkwQUBYF6jUHMoOpcxj6pPr/oaV9YMfh4P2eyKxNTdJGJXGe9kUPpLRydgoBq9NHluUfjsxKQ4STwG45+8TMZnXZOF3qQpW2Ny1shn5V2wSECZBHiTaTtshcIz6Kxew47nW9DQ2ITpbbalYTXdnaBOalKpKkS0r4/96QD2HrYQECAwEAAaOCAuEwggLdMB0GA1UdDgQWBBRHFQmUcuBtf6vI5ikCLF1uudlSezAfBgNVHSMEGDAWgBSqB1gVMhLVRX/DsU7Cy9JdkhJExjCCAQQGA1UdHwSB/DCB+TCB9qCB86CB8IaBt2xkYXA6Ly8vQ049RFBTSXNzdWVDQTAxLENOPUhEUVBSRElUU0lDQTAwMSxDTj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1UTEUsREM9RFBTP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludIY0aHR0cDovL2NybC5kcHMudGV4YXMuZ292L2NlcnRlbnJvbGwvRFBTSXNzdWVDQTAxLmNybDCB5QYIKwYBBQUHAQEEgdgwgdUwgacGCCsGAQUFBzAChoGabGRhcDovLy9DTj1EUFNJc3N1ZUNBMDEsQ049QUlBLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9VExFLERDPURQUz9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTApBggrBgEFBQcwAYYdaHR0cDovL2NybC5kcHMudGV4YXMuZ292L29jc3AwCwYDVR0PBAQDAgWgMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCKu3YYWw7zKHhZsih5egL4PJzHwhhI+/NoO2ljQCAWQCAQUwKQYDVR0lBCIwIAYIKwYBBQUHAwQGCisGAQQBgjcKAwQGCCsGAQUFBwMCMDUGCSsGAQQBgjcVCgQoMCYwCgYIKwYBBQUHAwQwDAYKKwYBBAGCNwoDBDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAgEApbhMNf/KZge1ZtpY9xpokh3Zuo3VbNnIi0A6V5PWE/UN8AXIvq6IsbjES+XLxecIkNmSBvZllSvEzZzSnDy/XFlqVGCYRWS8LDrm/1NAjyr4YXfRZyOTxE7W4RyyBsRpLRk2VsgCZ8wpO9kmG8vogp+6Bd0DQQayuTrJbAtlw0SBBgCd6pIWfG9LoCsvKKmNd6xi65clijxxWm82w14KqlUEcR/mgFoCJLJ1qpshHmqK5nc283nDmlnKB1jdOBHOZ3S6j5YpLlxxWHZhntwd01w/wKntwAZDHSagRCSvWz+gct47//chfjcCIzaUqTTY9Pw0VjDy+KDgOaVp2lAlHEWs5Ts3nT0AfTJDSDtDmOikyfAJlUIM08jfKUIIMOh1w/DC4SEFESl8vnmOimnqN2bFO5KmyulMD4XwWQBxuwmub1eR80Z3//hynXp6aCcUEaTswDmlws24Ecv9ILuSVohQC+WtJAB5bbRQTbbuYu+taabxGNl9Hyh9zTyNrbM3nG5GkaxtSYy2fNiVqzS88sXOShye3GEfgb0a/OFpC736wbMPV+I7HNbqGa9Zi+KdsJLA32cbnJO1g2yThdpT05uoikNNQrHuse0RtOZJdpLEnRejW96WQYHmxm/tlL64ZPskl5dnlUrbzTqQ9oyJqueDe1eP9jaId6NjAuKzLkQ=</wsse:BinarySecurityToken>
<wsu:Timestamp wsu:Id="TS-c1511394-ae6f-4a4c-b8c4-a97df1bbd782">
<wsu:Created>2017-11-02T22:02:30.558Z</wsu:Created>
<wsu:Expires>2017-11-02T22:07:30.558Z</wsu:Expires>
</wsu:Timestamp>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="SIG-d17430ac-1be2-410d-b4ed-389fa2c71d9c"
>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
>
<ec:InclusiveNamespaces
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="soap" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
/>
<ds:Reference
URI="#TS-c1511394-ae6f-4a4c-b8c4-a97df1bbd782">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
>
<ec:InclusiveNamespaces
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="wsse soap" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
/>
<ds:DigestValue>oUUE187y3bNvLUk0KvKAMQi5oS0=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#_7f09a81a-706a-4d03-932e-c402c7af8d16">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
>
<ec:InclusiveNamespaces
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="soap" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
/>
<ds:DigestValue>J3b0s0Tc7Z9nwyg6ryeyXi5V7Wk=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>UED8ewbdSQUhh6k7Py+P+5wveYhhM8xwpaBhn5IYKqqPSFzQSkFCG3q7oN/tOL3Oe33N2Xm+zPD26Qr7t7LGSEIXUU3ALxtnf8MtS3FRo9C6pxPPC6QuN0dYupPFZnQpYtNBL9i9HIRB9dqh9I7NAdz3OGBCjdB8j0scP9V830YSf5fy5Sq5uC2uNV4Ee9tEmPbY1yStH8htwPHeQEAFlQ0eNRCGrKL30af9waXGPXetMfuoQPMIbNssImie5cz2O56DGs88bBLZZaLG8LdoouAti9v2DGmlL9A42iJjXs19jQy+HP+4zy/vteV/aRhk4t8Q+tJcbn3piy7+pFnuhQ==</ds:SignatureValue>
<ds:KeyInfo Id="KI-2b2d8678-1047-4bbb-a9f6-33de176b569e">
<wsse:SecurityTokenReference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="STR-2e70c6dd-87f9-449e-9659-e0853efef74f"
>
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"
>y5plsGZ1ujCONeUMI+FuNgfF8LU=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body>
<wst:RequestSecurityToken
xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wsp:AppliesTo xmlns:wsp="http://www.w3.org/ns/ws-policy">
<wsa:EndpointReference
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Address>https://localhost:8443/mock-vls-ws/services/mockAuthenticationService</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Lifetime
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
>
<wsu:Created>2017-11-02T22:02:29.214Z</wsu:Created>
<wsu:Expires>2017-11-02T22:07:29.214Z</wsu:Expires>
</wst:Lifetime>
<wst:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</wst:TokenType>
<wst:KeySize>256</wst:KeySize>
<wst:Entropy>
<wst:BinarySecret
Type="http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce"
>0UEx1yrKYAbPt0/m6tuSeyjFvVV4bE1bvN97D9lT0bw=</wst:BinarySecret>
</wst:Entropy>
<wst:ComputedKeyAlgorithm>http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1</wst:ComputedKeyAlgorithm>
<wst:Renewing />
</wst:RequestSecurityToken>
</soap:Body>
</soap:Envelope>
Here is my Spring Endpoint config:
<bean id="Aamva_Authentication_Request"
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature" />
<entry key="user" value="dls-vls-mock-service-client-key" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass"
value="gov.uscis.uscis.xsd.esb.authentication.AuthenticationServicePasswordCallback"
/>
<entry key="decryptionPropFile"
value="cxf/cxf-crypto.properties" />
<entry key="signaturePropFile"
value="cxf/cxf-crypto.properties" />
<entry key="signatureUser"
value="dls-vls-mock-service-client-key" />
<entry key="signatureKeyIdentifier" value="X509KeyIdentifier "
/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken;{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://www.w3.org/2000/09/xmldsig}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body;"
/>
<!--
<entry key="encryptionPropFile"
value="cxf/cxf-crypto.properties" />
<entry key="encryptionParts"
value="{Content}{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Body;" />
-->
</map>
</constructor-arg>
</bean>
<bean id="Aamva_Authentication_Response"
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature" />
<entry key="user" value="dls-vls-mock-service-client-key" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass"
value="gov.uscis.uscis.xsd.esb.authentication.AuthenticationServicePasswordCallback"
/>
<entry key="signaturePropFile"
value="cxf/cxf-crypto.properties" />
<entry key="signatureKeyIdentifier" value="X509KeyIdentifier "
/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken;{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://www.w3.org/2000/09/xmldsig}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body;"
/>
<!--
<entry key="encryptionPropFile"
value="cxf/cxf-crypto.properties" />
<entry key="encryptionParts"
value="{Content}{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Body;" />
-->
</map>
</constructor-arg>
</bean>
<jaxws:endpoint id="mockAuthenticationServiceEndpoint" bus="cxf"
address="/mockAuthenticationService"
implementor="gov.uscis.uscis.xsd.esb.authentication.AuthenticationServiceImpl"
>
<jaxws:binding>
<soap:soapBinding mtomEnabled="true" version="1.2" />
</jaxws:binding>
<jaxws:inInterceptors>
<ref bean="Aamva_Authentication_Request" />
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="Aamva_Authentication_Response" />
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:endpoint>
Since adding the signatureParts entries, now I am getting:
2017-11-02 21:40:11.369 WARN [org.apache.cxf.common.logging.LogUtils]
Interceptor for {http://aamva.org/authentication/3.1.0}AuthenticationService
has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Message part
{http://schemas.xmlsoap.org/ws/2005/02/trust}RequestSecurityToken was not
recognized. (Does it exist in service WSDL?)
I am out of my depth here. Can anyone suggest how to get the JAX:WS markup to
match up with the WSDL policy?
Thanks.