9

I'm trying to access a web service secured by a certificate. The security is setup on IIS and the web service is behind it.

I don't think WS-SECURITY will do this type of authentication. Is there any way to pass the client certificate when you call the web service?

I'm just getting an IIS Error Page that says "The page requires a client certificate".

I'm using CXF 2.1.4

ScArcher2
  • 85,501
  • 44
  • 121
  • 160

4 Answers4

7

Yes, this is possible using CXF. You will need to set up the client conduit. You can specify the keystore that contains the certificates that will allow you to access the web service in IIS. As long as the certificate you are using here is a known allowed client in IIS, you should be ok.

<http:conduit name="{http://apache.org/hello_world}HelloWorld.http-conduit">

   <http:tlsClientParameters>
       <sec:keyManagers keyPassword="password">
            <sec:keyStore type="JKS" password="password"
                 file="src/test/java/org/apache/cxf/systest/http/resources/Morpit.jks"/>
       </sec:keyManagers>
       <sec:trustManagers>
           <sec:keyStore type="JKS" password="password"
                file="src/test/java/org/apache/cxf/systest/http/resources/Truststore.jks"/>
       </sec:trustManagers>

       ...

   </http:tlsClientParameters>

Sample from: CXF Wiki

Freiheit
  • 8,408
  • 6
  • 59
  • 101
Chris Dail
  • 25,715
  • 9
  • 65
  • 74
1

Above answer is correct but adding to that ....

Your client bean should be as following (for this SSL working fine):

<jaxws:client id="helloClient" serviceClass="demo.spring.HelloWorld" address="http://localhost:9002/HelloWorld" />

If you define the client bean as following SSL will not work:

<bean id="proxyFactory" 
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo.spring.HelloWorld"/>
<property name="address" value="http://localhost:9002/HelloWorld"/>
</bean> 
Bo.
  • 2,547
  • 3
  • 24
  • 36
1

As mentioned by @geg you need to add interceptor to your JaxWsProxyFactoryBean and use HttpConduit.

Here is the sample code you can refer.
this code will guide how to set TLSClientParameters

Ali
  • 1,480
  • 2
  • 20
  • 30
0

To do it in programatically, create an interceptor and add it to your JaxWsProxyFactoryBean with factory.getOutInterceptors().add(new TLSInterceptor()).

public class TLSInterceptor extends AbstractPhaseInterceptor<Message> {

    public TLSInterceptor() {
        super(Phase.SETUP);
    }

    @Override
    public void handleMessage(final Message message) throws Fault {
            final Conduit conduit = message.getExchange().getConduit(message);
            if (conduit instanceof HTTPConduit) {
                final HTTPConduit httpConduit = (HTTPConduit) conduit;
                final TLSClientParameters tlsClientParameters = ObjectUtils.firstNonNull(httpConduit.getTlsClientParameters(), new TLSClientParameters());

               // configure the params

                httpConduit.setTlsClientParameters(tlsClientParameters);
            }
        }
}
geg
  • 4,399
  • 4
  • 34
  • 35