Search code examples
httpscxfx509ws-security

Apache CXF - how to use ws-securitypolicy with ws-secureconversation over HTTPS


I am building a client for a SOAP web service provided by an external party. The WSDL uses policy assertions to specify the security. This includes using an X509 certificate, SecureConversationToken, and transport via HTTPS.

If I comment out the HTTPS parts of the policy I am able to generate a request from my client. However when I uncomment these I get an exception saying that the Security configuration could not be detected:

Caused by: org.apache.cxf.ws.policy.PolicyException: Security configuration could not be detected. Potential cause: Make sure jaxws:client element with name attribute value matching endpoint port is defined as well as a ws-security.signature.properties element within it.
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.policyNotAsserted(AbstractBindingBuilder.java:315)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureBuilder(AbstractBindingBuilder.java:1851)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureBuilder(AbstractBindingBuilder.java:1748)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.doX509TokenSignature(TransportBindingHandler.java:359)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleEndorsingToken(TransportBindingHandler.java:297)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleEndorsingSupportingTokens(TransportBindingHandler.java:252)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleBinding(TransportBindingHandler.java:153)

If I place a breakpoint where the exception is thrown I see that the assertion it is trying to satisfy is X509Token.

The policy is:

<wsp:Policy wsu:Id="WSHttpBinding_IFeederService_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>

The parts I remove to make it "work" without HTTPS are the first sp:TransportBinding and the second sp:TransportToken.

My configuration is:

<jaxws:client name="{http://tempuri.org/}IFeederService" createdFromAPI="true">
    <jaxws:properties>
        <entry key="ws-security.callback-handler.sct">
            <bean class="nz.govt.moh.common.security.FixedWSPasswordCallbackHandler">
                <property name="password" value="password" />
            </bean>
        </entry>
        <entry key="ws-security.signature.properties.sct" value="spring/eps-test-client-keystore.properties" />
    </jaxws:properties>
</jaxws:client>

The properties file defines:

org.apache.ws.security.crypto.merlin.keystore.file
org.apache.ws.security.crypto.merlin.keystore.password
org.apache.ws.security.crypto.merlin.keystore.type
org.apache.ws.security.crypto.merlin.keystore.alias

I've tried adding ws-security.callback-handler and ws-security.signature.properties as well (with same values as the sct ones). Also tried adding ws-security.username and ws-security.username.sct. It works without any of these though with the HTTPS bits off.

Also when I enable HTTPS I add:

<http:conduit name="{http://tempuri.org/}IFeederService.http-conduit">
    <http:tlsClientParameters>
        <sec:trustManagers>
            <sec:keyStore file="${jetty.eps.ssl.keystore.file}" password="${jetty.eps.ssl.keystore.password}" type="${jetty.eps.ssl.keystore.type}" />
        </sec:trustManagers>
        <sec:cipherSuitesFilter>
            <sec:include>.*_EXPORT_.*</sec:include>
            <sec:include>.*_EXPORT1024_.*</sec:include>
            <sec:include>.*_WITH_DES_.*</sec:include>
            <sec:include>.*_WITH_AES_.*</sec:include>
            <sec:include>.*_WITH_NULL_.*</sec:include>
            <sec:exclude>.*_DH_anon_.*</sec:exclude>
        </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
</http:conduit>

I am using CXF version 2.7.17 with Java 6. (I tried upgrading to 3.0.x but encountered other issues although I may give that another go now that I have a better understanding of CXF.)

Any ideas as to what I am doing wrong? Is there something else that I need to specify in order to use HTTPS? Is there a working example that uses securitypolicy, secureconversation, and HTTPS all together?

Thanks for your help, Damon


Solution

  • It turned out that I was using the wrong name for the jaxws:client. I had taken the end portion of the name from wsdl:portType instead of wsdl:port. When I commented out the HTTPS bits in the WSDL, it got as far as actually sending out a request even though the name was wrong, however with the full WSDL it complained because it couldn't find the security configuration.