Contact Us 1-800-596-4880

Securing a SOAP API

Mule runtime engine version 3.8 reached its End of Life on November 16, 2021. For more information, contact your Customer Success Manager to determine how to migrate to the latest Mule version.

Enterprise

When a SOAP API exposes private-network data to the outside world, that data travels through four to seven separate protocol layers (see TCP/IP or OSI) thus introducing potential security vulnerabilities. Implementing security at a higher layer on the protocol stack — the application layer, for instance — generally provides better protection than an implementation at the lower transport layer, which provides only HTTPS security.

To implement application-layer security, enable WS-security on your SOAP API. WS-security is a CXF configuration that defines a new SOAP header capable of carrying various security tokens that systems use to identify a API caller and check privileges. WS-security can include the following things:

  • encryption

  • digital signature

  • timestamp

You can also add a custom validator to the CXF Component.

Enabling WS-Security

To enable WS-security on a SOAP API in your application, you must add WS-configurations to the CXF Component in your flow. This approach enables WS-security locally within your flow for one API only.

To the Mule flow that involves an API, add a CXF Component to publish, consume, or create a proxy for an API. Complete the following steps to configure WS-security on the CXF component.

Studio Visual Editor

You configure a security token to identify API callers using a key-value pair where the value is a CXF WSS4J security-configuration text string or a value reference:

  • The string value is one of the following constants:

    • WSConstants, a class to define the kind of access the server allows

    • WSHandlerConstants, a class to specify the names, actions, and other strings for data deployment of the WSS handler

  • The bean Value Reference is the name of the bean that the key references. For example, when the key is passwordCallbackRef, enter the name of the bean in the Value Reference field.

To configure the CXF component, you enter a string value UsernameToken in the value field under Add Configuration Element. In XML, this step mirrors the addition of a key-value pair inside the ws-config child element of a ws-security element. By adding configuration elements to your SOAP component, you are creating a map of key-value pairs that correspond to the CXF WSS4J security-configuration text strings.

To secure a SOAP API:

  1. Open the properties editor, then click the Security tab.

  2. Click (plus) in Add Configuration Element to create a new key-value pair.

    securing a soap api 063ca

    The cxf:property default key name appears.

  3. In the Key field, replace the default key with a name, for example action.

  4. Enter a value, for example UsernameToken, in the Value field.

    securing a soap api 52d2b
  5. Click Finish to save the key-value pair.

  6. Repeat these steps to add as many ws-security configurations as you need, then click OK.

Studio Visual Editor or Standalone

  1. To your CXF element (i.e. SOAP component), add a child element for cxf:ws-security.

  2. Within the cxf:ws-security child element, add a child element for cxf:ws-config.

  3. Within the cxf:ws-config child element, add a child element for cxf:property.

  4. Add two attributes to the cxf:property child element according to the table below. Be sure to enter either a value `OR a `value-ref; the two are mutually exclusive.

    Attribute

    Description

    key

    Specify a name for the property.

    value

    Specify a WS Constant (a class to define the kind of access the server allows) or a WSHandlerConstant (a class to specify the names, actions, and other strings for data deployment of the WSS handler). For example, enter UsernameToken in the value field.

    value- ref

    Specify the bean that the key must reference. When the key must reference a bean (for instance, when the key is passwordCallbackRef), specify the name of the bean as the value-ref.

  5. Repeat the preceding step to add as many WS-security configurations as you want to your API. Refer to the following sample code:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd">

<http:listener-config name="listener-config" host="localhost" port="8081"/>
<flow name="Creation1Flow1" doc:name="Creation1Flow1">
    <http:listener config-ref="listener-config" path="/" doc:name="HTTP Connector"/>
    <cxf:jaxws-service doc:name="SOAP">
        <cxf:ws-security>
            <cxf:ws-config>
                <cxf:property key="action" value="UsernameToken"/>
            </cxf:ws-config>
        </cxf:ws-security>
    </cxf:jaxws-service>
</flow>

Adding a Token Validator

If you have enabled WS-Security on your SOAP API in Mule, you can also configure the CXF component to delegate authentication of the message credentials it transmits or receives.

A CXF component might get bogged down with processing tasks and authenticating messages. To lighten the load, you can instruct WS-security to delegate certain message authentication tasks to a Token Validator, including:

  • Validating the UsernameToken in cases where the CallbackHandler implementation does not have access to the password

  • Validating the attributes of a received SAML assertion

  • Dispatching a received security token to a third-party security service for validation

Complete the following procedure to add token validators to your API.

Studio Visual Editor

  1. On the Security tab of a CXF component in a flow, click one or more of the checkboxes to delegate message authentication tasks to token validators.

    securing a soap api 1f421

    The token validators serve the following purposes:

    Token Validator Purpose

    User Name

    Authenticates the user name and password credentials associated with each message in a manner similar to HTTP Digest authentication.

    SAML 1

    Checks messages against SAML 1.1 assertion statements in order to approve or reject access to the API.

    SAML 2

    Checks messages against SAML 2.0 assertion statements in order to approve or reject access to the API.

    Timestamp

    Examines the timeliness of messages – when they were created and received, and when they expire – to make decisions about which messages to process.

    Signature

    Examines the digital signature attached to messages to make decisions about which messages to process.

    Binary Security Token

    Examines binary encoded security tokens (such as Kerberos) to make decisions about which messages to process.

  2. In the Bean field associated with the token validator you select, select an existing bean from the drop-down.

    Your token validator references this bean to apply, replace, or extend the default behavior associated with a security token.

    Alternatively, if you have not yet created any beans, click the (plus) button to open a new properties panel for creating and configuring a new bean. The bean imports the Java class you have built to specify the custom validator override behavior.

    securing a soap api d8161
  3. Click OK.

Studio XML Editor or Standalone

  1. Above all flows in your Mule project, create a global spring:bean element to import the Java class you have built to specify the token validator’s behavior. Refer to code sample below.

     View Java code for Bean Creation
    . To the CXF element in your flow, add a child element (below any `cxf:ws-config` elements you may have added) for `cxf:ws-custom-validator`.
    . To the `cxf:ws-custom-validator` child element, add a child element according to the type of action you want the validator to perform. Refer to the table below.
    Token Validator Purpose

    cxf:username-token-validator

    Authenticates the user name and password credentials associated with each message in a manner similar to HTTP Digest authentication.

    cxf:saml1-token-validator

    Checks messages against SAML 1.1 assertion statements in order to approve or reject access to the API.

    cxf:saml2-token-validator

    Checks messages against SAML 2.0 assertion statements in order to approve or reject access to the API.

    cxf:timestamp-token-validator

    Examines the timeliness of messages – when they were created and received, and when they expire – to make decisions about which messages to process.

    cxf:signature-token-validator

    Examines the digital signature attached to messages to make decisions about which messages to process.

    cxf:bst-token-validator

    Examines binary encoded security tokens (such as Kerberos) to make decisions about which messages to process.

  2. Add a ref attribute to the validator to reference the global spring:bean element which imports the Java class.

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd">

<spring:beans>
    <spring:bean id="customTokenValidator" name="Bean" class="org.mule.example.myClass"/>
</spring:beans>

<http:listener-config name="listener-config" host="localhost" port="8081"/>
<flow name="Creation1Flow1" doc:name="Creation1Flow1">
    <http:listener config-ref="listener-config" path="/" doc:name="HTTP Connector"/>
    <cxf:jaxws-service doc:name="SOAP">
        <cxf:ws-security>
            <cxf:ws-config>
                <cxf:property key="action" value="UsernameToken"/>
            </cxf:ws-config>
            <cxf:ws-custom-validator>
                <cxf:username-token-validator ref="Bean"/>
            </cxf:ws-custom-validator>
        </cxf:ws-security>
    </cxf:jaxws-service>
</flow>

Complete Code Example

For a complete explanation of the example application, see Anypoint Exchange.

<?xml version="1.0"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:core="http://www.mulesoft.org/schema/mule/core" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd  http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd  http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
    <spring:beans>
        <spring:bean class="com.mulesoft.mule.example.security.SAMLCustomValidator" id="Bean" name="samlCustomValidator"/>
    </spring:beans>
    <http:listener-config name="listener-config" host="localhost" port="63081" basePath="services"/>

    <flow doc:name="UnsecureServiceFlow" name="UnsecureServiceFlow">
        <http:listener config-ref="listener-config" path="unsecure" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Unsecure service" serviceClass="com.mulesoft.mule.example.security.Greeter"/>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
    <flow doc:name="UsernameTokenServiceFlow" name="UsernameTokenServiceFlow">
        <http:listener config-ref="listener-config" path="username" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Secure UsernameToken service" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="UsernameToken Timestamp"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
    <flow doc:name="UsernameTokenSignedServiceFlow" name="UsernameTokenSignedServiceFlow">
        <http:listener config-ref="listener-config" path="signed" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Secure UsernameToken Signed service" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="UsernameToken Signature Timestamp"/>
                    <cxf:property key="signaturePropFile" value="wssecurity.properties"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
    <flow doc:name="UsernameTokenEncryptedServiceFlow" name="UsernameTokenEncryptedServiceFlow">
        <http:listener config-ref="listener-config" path="encrypted" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Secure UsernameToken Encrypted service" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="UsernameToken Timestamp Encrypt"/>
                    <cxf:property key="decryptionPropFile" value="wssecurity.properties"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
    <flow doc:name="SamlTokenServiceFlow" name="SamlTokenServiceFlow">
        <http:listener config-ref="listener-config" path="saml" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Secure SAMLToken service" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenUnsigned Timestamp"/>
                </cxf:ws-config>
                <cxf:ws-custom-validator>
                    <cxf:saml2-token-validator ref="samlCustomValidator"/>
                </cxf:ws-custom-validator>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
    <flow doc:name="SignedSamlTokenServiceFlow" name="SignedSamlTokenServiceFlow">
        <http:listener config-ref="listener-config" path="signedsaml" doc:name="HTTP Connector"/>
        <cxf:jaxws-service doc:name="Secure SAMLToken Signed service" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenUnsigned Signature"/>
                    <cxf:property key="signaturePropFile" value="wssecurity.properties"/>
                </cxf:ws-config>
                <cxf:ws-custom-validator>
                    <cxf:saml2-token-validator ref="samlCustomValidator"/>
                </cxf:ws-custom-validator>
            </cxf:ws-security>
        </cxf:jaxws-service>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service"/>
    </flow>
</mule>

See Also

  • Learn more about configuring a CXF component in your Mule application.