Skip to content

Secured SOAP Client

Source

Call a SOAP web service secured with SSL/TLS and username/password authentication -- all configured through properties and a Camel SSL bean.

What You'll Learn

  • How to configure SSL/TLS transport security with Camel's SSLContextParameters
  • How to add username/password authentication to a CXF SOAP endpoint
  • How Forage wires the SSL context and credentials into the CXF endpoint automatically

Scenario

The same HelloService from the basic SOAP client is now deployed behind HTTPS and requires authentication. The WSDL is at https://host:8443/ws/hello?wsdl, and the service requires a username and password.

You need both:

  • Transport-level security -- TLS for encrypted communication
  • Message-level authentication -- credentials sent with each request

Step 1: Configure SSL

Define an SSLContextParameters bean with the truststore generated by the setup script:

ssl-context.camel.yaml
- beans:
    - name: mySSLContext
      type: org.apache.camel.support.jsse.SSLContextParameters
      properties:
        trustManagers:
          keyStore:
            resource: "file:certs/truststore.jks"
            password: "changeit"
            type: "JKS"

The truststore contains the server's certificate, allowing the CXF client to verify the server during the TLS handshake. For mutual TLS (mTLS), add a keyManagers section with the client's keystore.

Step 2: Configure Forage

Add SSL and authentication properties to the basic SOAP client config:

application.properties
forage.securedClient.cxf.address=https://localhost:8443/ws/hello           # (1)!
forage.securedClient.cxf.wsdl.url=https://localhost:8443/ws/hello?wsdl
forage.securedClient.cxf.service.name={http://example.com/hello}HelloService
forage.securedClient.cxf.port.name={http://example.com/hello}HelloPort
forage.securedClient.cxf.data.format=PAYLOAD
forage.securedClient.cxf.logging.enabled=true

# Authentication
forage.securedClient.cxf.username=admin                                   # (2)!
forage.securedClient.cxf.password=secret                                  # (3)!

# SSL/TLS
forage.securedClient.cxf.ssl.context.parameters=mySSLContext              # (4)!
  1. Note https:// -- the endpoint uses TLS.
  2. Username for HTTP Basic authentication on the SOAP endpoint.
  3. Password for authentication.
  4. References the mySSLContext bean defined in ssl-context.camel.yaml.

The additions compared to the basic SOAP client:

  • forage.securedClient.cxf.username / forage.securedClient.cxf.password -- credentials injected into every request
  • forage.securedClient.cxf.ssl.context.parameters -- links to the SSL bean that configures the TLS trust chain

Step 3: Write the Route

The route itself is identical to the basic client -- security is handled entirely in the configuration layer:

route.camel.yaml
- route:
    id: cxf-soap-client-secured
    from:
      uri: timer
      parameters:
        timerName: soap-caller
        repeatCount: 1
        period: 5000
      steps:
        - setBody:
            constant:
              expression: >
                <sayHello xmlns="http://example.com/hello">
                  <name>Forage</name>
                </sayHello>
        - setHeader:
            name: operationName
            constant:
              expression: sayHello
        - setHeader:
            name: operationNamespace
            constant:
              expression: "http://example.com/hello"
        - to:
            uri: cxf:bean:securedClient
        - log:
            message: "Secured SOAP response: ${body}"
Route.java
public class Route extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("timer:soap-caller?repeatCount=1&period=5000")
            .setBody(constant(
                "<sayHello xmlns=\"http://example.com/hello\">"
                + "<name>Forage</name></sayHello>"))
            .setHeader("operationName", constant("sayHello"))
            .setHeader("operationNamespace",
                constant("http://example.com/hello"))
            .to("cxf:bean:securedClient")
            .log("Secured SOAP response: ${body}");
    }
}

Notice that the route code does not change at all -- the same pattern works for both unsecured and secured endpoints. All security is handled by Forage at the configuration level.

Running

camel run *

You should see:

Secured SOAP response: <sayHelloResponse xmlns="http://example.com/hello">
  <greeting>Hello Forage from secured CXF</greeting>
</sayHelloResponse>

If the TLS handshake fails, verify:

  • The truststore contains the server's certificate (or its CA)
  • The truststore password matches
  • The server address matches the certificate's CN or SAN

Key Takeaways

  • Security as configuration -- adding TLS and authentication to a SOAP client requires only property changes and an SSL bean definition. The route code stays the same.
  • No interceptor boilerplate -- without Forage, configuring CXF SSL requires programmatic HTTPConduit access and custom interceptor chains. Forage handles this from a single property reference.
  • Named beans -- each endpoint has a descriptive name (securedClient). The SSL context bean (mySSLContext) is reusable across multiple CXF endpoints by referencing it by name.