Contact Us 1-800-596-4880

SOAP Web Service Security Example

Mule Runtime Engine versions 3.5, 3.6, and 3.7 reached End of Life on or before January 25, 2020. For more information, contact your Customer Success Manager to determine how you can migrate to the latest Mule version.

Enterprise Edition, CloudHub

This example demonstrates how to apply varying levels of security to a SOAP Web service.

Web Service Security

When a Web service 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 (a CXF configuration) on your Web service. WS-security defines a new SOAP header which is capable of carrying various security tokens that systems use to identify a Web service caller’s identity and privileges.

Assumptions

This document describes the details of the example within the context of Anypoint™ Studio. Where appropriate, the XML configuration follows the Studio interface screenshot in an expandable section.

This document assumes that you are familiar with Mule Runtime and the Anypoint Studio interface. To increase your familiarity with Anypoint Studio, consider completing one or more Anypoint Studio Tutorials.

Example Use Case

The example application applies different security measures to five of the six variations of a SOAP service it exposes (the sixth is unsecure). Each variation accepts end user salutation requests via a Web browser, then responds with a personalized greeting. For instance, when a user submits his name, “John”, to one of the six variations, he receives a response that reads, Hello John. The table below outlines the six variations in the WS-Security example application, and the security Mule applies to each.

Web Service Name Type of Security Description

UnsecureServiceFlow

none

Processes all requests.

UsernameTokenServiceFlow

UsernameToken

Processes requests with a valid username and password.

UsernameTokenSignedServiceFlow

UsernameToken + signature

Processes requests with a valid username and password, and a valid digital signature.

UsernameTokenEncryptionServiceFlow

UsernameToken + encryption

Processes encrypted requests with a valid username and password.

SamlTokenServiceFlow

SAML2

Processes requests in conjunction with an identity provider to verify message security.

SignedSamlTokenServiceFlow

SAML2 + signature

Processes requests with valid digital signature in conjunction with an identity provider to verify message security.

This application also includes several variations of a client-side Web service to ensure a functional example. These service-clients enable end users to submit salutation requests to the server-side Web service. Refer to the Client-Side Flows section below for more details.

This document helps you understand some of the ways you can apply security to a SOAP Web service in Mule ESB applications. To understand more about Mule ESB’s ability to integrate services and systems, access the Mule examples and see other applications in action.

Set Up and Run the Example

You can create template applications straight out of the box in Anypoint Studio or Mule Standlone (Mule ESB without Studio). You can tweak the configurations of these use case-based templates to create your own customized applications in Mule.

Follow the procedure below to create, then run the WS-Security example application.

  1. Create, then run the example application in Anypoint Studio or Standalone.

  2. Open your Web browser.

  3. In the address bar, type localhost:63080/client?clientType=unsecure&name=John

  4. Press enter to elicit a response from the WS-Security application (see image below).

    image::first-response.png[first_response]

  5. Adjust the URL to change the name from John to your name, then press enter to elicit a new response from the application.

  6. Adjust the clientType parameter from `unsecure`to any of the following five types (note that each type is case-sensitive):

    • usernameToken

    • usernameTokenSigned

    • usernameTokenEncrypted

    • samlToken

    • samlTokenSigned

  7. Press enter to elicit a new response from the application (see example, below).

    image::second-response.png[second_response]

Regardless of the clientType you use to submit a request, Mule returns the same response. The type of security Mule uses to process the message is not reflected in the content of message, so even though Mule processes each request in a different way, the content of the response remains unchanged.

Alternative Set Up

Rather than interacting with the application via a Web browser, you can submit end user requests via the SecureClient java class within Anypoint Studio.

  1. Complete the procedure to create, then run the Security template in Anypoint Studio, or the Security example in Mule Standalone (Mule ESB without Studio).

  2. In the Package Explorer, navigate to src/main/java, then expand the com.mulesoft.mule.example.security folder to reveal the SecureClient file.

    image::securitype.png[]

  3. Right-click the SecureClient file, then select Run As > Java Application.

  4. In the Console, Mule displays a menu which lists the different types of requests you can submit to the WS-Security application.

    image::console.png[]

  5. Click below the last line in the list, q. Quit, to activate your cursor in the console pane.

  6. Below the last line, type 2, then press enter to submit a request with Username Token security to the WS-Security application.

  7. Mule processes the request and returns a response in the console pane which reads, Hello Mule.

    image::response.png[]

  8. Mule displays the same menu of request submission options in the console again. Type another number, 1 – 9, below the last list item, then press enter.

  9. Mule processes the request and returns a response in the console pane which reads, Hello Mule.

  10. When you wish to terminate the Java application, type q, then press enter.

How it Works

This example application consists of several flows and subflows. Each of these flows exposes a variation of the same Web service which processes end user requests for a salutation. The only difference between the flows is the type of Web service security each employs.

The sections below offer flow-by-flow descriptions of the WS-Security application’s actions as it processes end user requests. The Web service variation of each flow in this document is more secure than the one preceding it.

UnsecureService Flow

Studio Visual Editor

unsecureService

Studio XML Editor or Standalone

<flow name="UnsecureServiceFlow" doc:name="UnsecureServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/unsecure" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Unsecure service"/>
        <component class="com.mulesoft.mule.example.security.GreeterService" doc:name="Greeter Service" />
    </flow>

When an end user submits an unsecure salutation request, the Web service client sends a simple SOAP request message (see below) to the UnsecureService flow in the WS-Security application.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns2:greet xmlns:ns2="http://security.example.mule.mulesoft.com/">
            <name>John</name>
        </ns2:greet>
    </soap:Body>
</soap:Envelope>

The request-response HTTP Endpoint in this flow receives the end user request. Because it has a two-way message exchange pattern, this HTTP endpoint is responsible for both receiving and returning messages.

A JAX-WS service, the CXF Component in this flow evaluates the message according to its security configurations. In this case, the Web service is unsecure (see image below) so the CXF component processes all requests it receives.

Studio Visual Editor

unsecuresoap

Studio XML Editor or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Unsecure service"/>

The Java Component executes a simple script to prepare a personalized salutation for the end user.

Where is the Java code?

To access the Java code in Anypoint Studio, navigate to the source file in the Package Explorer.

Find the Java: . In your WS-Security project, navigate to src/main/java > com.mulesoft.mule.example.security. . Double-click the Greeter.java file to open it in a new tab on the Studio canvas (see image below).

+ image::greeter.png[]

+ To access the Java code in Mule Standalone, navigate to the source file in the example folder on your local drive.

+ . Navigate to the Mule Standalone folder on your local drive. . Navigate to examples > security > src > main > java > com > mulesoft > mule > example > security. . Double-click to open the Greeter.java file.

Finally, the HTTP endpoint returns a simple SOAP response (see below) to the client.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns2:greetResponse xmlns:ns2="http://security.example.mule.mulesoft.com/">
            <name>Hello John</name>
        </ns2:greetResponse>
    </soap:Body>
</soap:Envelope>

UsernameTokenService Flow

Studio Visual Editor

usernameTokenService

Studio XML Editor or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken service">
            <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>

When an end user submits a usernameToken salutation request, the Web service client sends a SOAP request message (see below) to the UsernameTokenService flow in the WS-Security application.

SOAP Request Message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <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="1">
            <wsu:Timestamp wsu:Id="TS-2">
                <wsu:Created>2012-08-29T02:58:29.834Z</wsu:Created>
                <wsu:Expires>2012-08-29T03:03:29.834Z</wsu:Expires>
            </wsu:Timestamp>
            <wsse:UsernameToken wsu:Id="UsernameToken-1">
                <wsse:Username>joe</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
                    q0JPIhBbzqsE7dz71CoUjzBJbxs=
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    hdSN3eeqCZxr4huNcRTG+A==
                </wsse:Nonce>
                <wsu:Created>2012-08-29T02:58:29.831Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soap:Header>
    <soap:Body>
        <ns2:greet xmlns:ns2="http://security.example.mule.mulesoft.com/">
            <name>John</name>
        </ns2:greet>
    </soap:Body>
</soap:Envelope>

Like the UnsecureService flow, this flow uses an HTTP endpoint to receive the request and a CXF component to process the message. In this case, however, the CXF component’s configuration specifies the action, which is a list of WS-security features against which Mule validates a message. This component’s UsernameToken specification verifies the following:

  • Username and password — confirms the client’s username and password are valid

  • Timestamp — verifies that the message is not stale

Studio Visual Editor

soap2

Studio XML Editor or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken service">
            <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>

Username and password?

To demonstrate a functional example, the WS-Security application includes several client-side flows which provide the server-side flows with security information.

Normally, an independent Web service client provides the Web service provider with end user security information, such as username and password. In this case, however, Mule generates this information within its service-clients flows to simulate secure request submissions.

Refer to the Client-Side Flows section below for more details.

Next, the Java Component executes a simple script to prepare a personalized salutation for the end user. Lastly, the HTTP endpoint returns a simple SOAP response to the client.

UsernameTokenSignedService Flow

Studio Visual Editor

usernameTokenSigned

Studio XML Editor or Standalone

<flow name="UsernameTokenSignedServiceFlow" doc:name="UsernameTokenSignedServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/signed" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken Signed service">
            <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>

This flow validates the digital signature of a message. A message with a digital signature — in addition to username, password and timestamp — is more secure than a message without.

When an end user submits a usernameTokenSigned salutation request, the Web service client sends a SOAP request message (see below) to the UsernameTokenSignedService flow in the WS-Security application.

SOAP Request Message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <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="1">
            <wsu:Timestamp wsu:Id="TS-12">
                <wsu:Created>2012-08-29T03:24:26.100Z</wsu:Created>
                <wsu:Expires>2012-08-29T03:29:26.100Z</wsu:Expires>
            </wsu:Timestamp>
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-11">
                <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="#id-10">
                        <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=""/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>CPmeTSkR/UjaGQfTqNLXHQXOPGU=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>Tjdon+T59I9YMI+hDwXWHWT1mIwf0LS1ZpzB57KB3aM7+XebbHKtKjbEnughtDDHEW7gfAvcBS9H
                    goXeqI8lCu7HqRixX0LPrkpUKW1FUbjl0zQLOrI1quPS557TABKpfEKbu1wwoZQTyVOWjs1+R8qU
                    CXsJsT+iL4UVQrbMVNg=
                </ds:SignatureValue>
                <ds:KeyInfo Id="KI-E847A979F41D3E818513462106660948">
                    <wsse:SecurityTokenReference wsu:Id="STR-E847A979F41D3E818513462106660949">
                        <ds:X509Data>
                            <ds:X509IssuerSerial>
                                <ds:X509IssuerName>CN=joe,OU=joe,O=joe,L=joe,ST=joe,C=US</ds:X509IssuerName>
                                <ds:X509SerialNumber>1262035674</ds:X509SerialNumber>
                            </ds:X509IssuerSerial>
                        </ds:X509Data>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
            <wsse:UsernameToken wsu:Id="UsernameToken-9">
                <wsse:Username>joe</wsse:Username>
                <wsse:Password
                        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
                    vzL3k/289R5JFREMIFBPAyDbe6c=
                </wsse:Password>
                <wsse:Nonce
                        EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
                    I+dSbnJQoYzktN+RuF8DLQ==
                </wsse:Nonce>
                <wsu:Created>2012-08-29T03:24:26.093Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soap:Header>
    <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
               wsu:Id="id-10">
        <ns2:greet xmlns:ns2="http://security.example.mule.mulesoft.com/">
            <name>John</name>
        </ns2:greet>
    </soap:Body>
</soap:Envelope>

The only difference between the UsernameTokenService and UsernameTokenSignedService flows is the CXF component’s configuration. In this flow, the component includes a signature action, signaturePropFile (see image below), which Mule uses to validate the digital signature.

Studio Visual Editor

soap3

Studio XML Editor or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken Signed service">
            <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>

The signaturePropFile property specifies the keystore against which Mule must validate the digital signature on the message. The keystore, which is a repository containing security certificates, resides in the wssecurity.properties file embedded in the application.

Where is the wssecurity.properties File?

To access the wssecurity.properties file in Studio, navigate to the source file in the Package Explorer.

  1. In your WS-Security project, navigate to src/main/resources.

  2. Double-click the wssecurity.properties file to open it in a new tab on the Studio canvas (see image below).

    image::ws-security-properties.png[ws_security_properties]

The wssecurity.properties file contains the following properties:

  • org.apache.ws.security.crypto.merlin.file=keystore.jks

  • org.apache.ws.security.crypto.merlin.keystore.password=keyStorePassword

To validate the digital signature, Mule uses a Java keytool command to verify that the certificate for user joe exists in the keystore (see image below).

+ image::keystore.png[]

Note that this example certificate is self-signed (i.e. the Owner and Issuer are the same entity). Normally, a trusted third party Issuer, such as VeriSign, issues the certificate.

UsernameTokenEncryptedService Flow

Studio Visual Editor

UsernameTokenEncrypted

Studio XML Editor or Standalone

<flow name="UsernameTokenEncryptedServiceFlow" doc:name="UsernameTokenEncryptedServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/encrypted" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken Encrypted service">
            <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>

In the preceding flows, the header of the SOAP message contained all the message’s security information, and the body of the message was completely transparent. This flow not only validates all the message using all the security information in the SOAP header, it decrypts the encrypted content in the body of the message. A message with an encrypted body is more secure than one with unencrypted content.

When an end user submits a usernameTokenEncrypted salutation request, the Web service client sends a SOAP request message (see below) to the UsernameTokenEncryptedService flow in the WS-Security application.

SOAP Request Message:
<soap:Body>
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-15"
                            Type="http://www.w3.org/2001/04/xmlenc#Content">
            <xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
                                   Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <wsse:SecurityTokenReference
                        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                        xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
                        wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
                    <wsse:Reference URI="#EK-E847A979F41D3E8185134621148888310"/>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                <xenc:CipherValue xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                    LcdVnOdPMSLvqSvqWZxojAT9MKDs5Qq2MmXafeqIb+h8LYQFvXV0Und2E6eyXp+ZxYVz+E3UdfEH
                    BvsbguT8y4MelnAagYGJl6MushFPOQ0ZRr0ZiuOkLbJlMloFFWz6jDEWekLngm84uAKu1vy37PMW
                    fXBkWFWC30fjVXk3pW8mkDXShiWaI+0a1j9qCJJMg81UwtI1xV0+0DSxs7wyQXLNjdc8ixfqLahW
                    y4wZR9g=
                </xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
</soap:Body>

In this flow, the CXF component must validate the username, password, timestamp and digital signature before decrypting the body of the SOAP message. Mule uses the keystore to perform the decryption.

Studio Visual Editor

soap4

Studio XML Editor or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure UsernameToken Encrypted service">
            <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>

The signaturePropFile property specifies the keystore which Mule uses to perform two tasks:

  1. Validate the digital signature on the message

  2. Decrypt the body of the SOAP message

How is the Message Body Encrypted?

To demonstrate a functional example, the WS-Security application includes several client-side flows which provide the server-side flows with security information.

The CXF Component in the client-side usernameTokenEncrypted subflow encrypts the body of the SOAP message (see image below).

subflow2
2encrypt

Refer to the Client-Side Flows section below for more details.

SAMLTokenService Flow

Studio Visual Editor

samlToken

Studio XML Editor or Standalone

<flow name="SamlTokenServiceFlow" doc:name="SamlTokenServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/saml" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure SAMLToken service">
            <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>

This flow uses the SAMLTokenUnsigned timestamp action to validate SAML2 assertions. A Web service uses Security Assertion Markup Language (SAML) to manage single sign-on (SSO) authentication. Assuming that an external resource has already authenticated a user — confirmed username and password, for example — the SAML token in the SOAP header of a message contains one or more subjects to confirm that the original authenticator is trustworthy. SAML offers two different methods for a Web service to gauge the trustworthiness of a message’s sender.

  1. Sender Vouches — The message sender must prove to the Web service that it is trustworthy. For example, a sender includes authenticity subjects in the SOAP header of a message, or provides a digital signature to prove its identity and trustworthiness.

  2. Holder of Key — The message receiver must confirm the trustworthiness of the sender. To do so, it demands that a message contain a SAML token subject which, in turn, contains a key from a trusted source (for example, an X.509 certificate from VeriSign).

For more information on SAML, refer to the saml.xml.org knowledge base.

When an end user submits a samlTokenSigned salutation request, the Web service client sends a SOAP request message (see below) to the SignedSAMLTokenService flow in the WS-security application.

SOAP Request Message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <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="1">
            <wsu:Timestamp wsu:Id="TS-16">
                <wsu:Created>2012-08-29T03:57:49.098Z</wsu:Created>
                <wsu:Expires>2012-08-29T04:02:49.098Z</wsu:Expires>
            </wsu:Timestamp>
            <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             ID="_E847A979F41D3E8185134621266899411" IssueInstant="2012-08-29T03:57:49.004Z"
                             Version="2.0" xsi:type="saml2:AssertionType">
                <saml2:Issuer>self</saml2:Issuer>
                <saml2:Subject>
                    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
                                  NameQualifier="www.example.com">AllowGreetingServices
                    </saml2:NameID>
                    <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"/>
                </saml2:Subject>
                <saml2:Conditions NotBefore="2012-08-29T03:57:49.090Z" NotOnOrAfter="2012-08-29T04:02:49.090Z"/>
                <saml2:AuthnStatement>
                    <saml2:AuthnContext>
                        <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password
                        </saml2:AuthnContextClassRef>
                    </saml2:AuthnContext>
                </saml2:AuthnStatement>
            </saml2:Assertion>
        </wsse:Security>
    </soap:Header>
    <soap:Body>
        <ns2:greet xmlns:ns2="http://security.example.mule.mulesoft.com/">
            <name>John</name>
        </ns2:greet>
    </soap:Body>
</soap:Envelope>

In this flow, the CXF component uses the Sender Vouches method to confirm the trustworthiness of the message sender. The SAMLTokenUnsigned Timestamp action ensures that the Web service only processes messages that contain a valid subject.

Rather than perform all the security validation itself, the CXF component delegates the validation to other elements.

In this example, the CXF component delegates the chore of validating the SAML Token to the SAML2 Token Validator. (In Studio, a checked SAML 2 box indicates this delegation.) The SAML2 Token Validator references a custom SAML2 token validator (see below, left), configured as a Spring bean, to determine how to validate the SAML token. The samlCustomValidator bean uses a Java class, com.mulesoft.mule.example.security.SAMLCustomValidator, to confirm the contents of the SAML subject are correct (see Java code below). In this case, Mule validates that the subject’s NameID is AllowGreetingService.

Studio Visual Editor

samldelegate
samlge

Studio XML Editor

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure SAMLToken service">
            <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>
Java Class:
public class SAMLCustomValidator extends SamlAssertionValidator
{
    @Override
    public Credential validate(Credential credential, RequestData data) throws WSSecurityException
    {
        Credential returnedCredential = super.validate(credential, data);
        //
        // Do some custom validation on the assertion
        //
        AssertionWrapper assertion = credential.getAssertion();
        if (!"self".equals(assertion.getIssuerString()))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        if (assertion.getSaml2() == null)
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        String confirmationMethod = assertion.getConfirmationMethods().get(0);
        if (confirmationMethod == null)
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }
        if (!OpenSAMLUtil.isMethodSenderVouches(confirmationMethod))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        if(!"AllowGreetingServices".equals(assertion.getSaml2().getSubject().getNameID().getValue()))
        {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
        }

        return returnedCredential;
    }
}

For Mule Studio Users

To access the SAMLCustomValidator Java class in Studio, navigate to the source file in the Package Explorer.

  1. In your WS-Security project, navigate to src/main/java > com.mulesoft.mule.example.security.

  2. Double-click the SAMLCustomValidator.java file to open it in a new tab on the Studio canvas (see image below).

SAMLCustomValidator

How Does the Web Service Client Send a SAML2 Assertion?

To demonstrate a functional example, the WS-Security application includes several client-side flows which provide the server-side flows with security information.

The CXF Component in the client-side samlToken subflow uses a SAMLCallbackHandler (see Java code below this box) to populate the assertion it sends to the Web Service. (see image below).

saml7
SAMLCallbackHandler Class:
package com.mulesoft.mule.example.security;

import java.io.IOException;
import java.util.Collections;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.saml.ext.SAMLCallback;
import org.apache.ws.security.saml.ext.bean.AuthenticationStatementBean;
import org.apache.ws.security.saml.ext.bean.SubjectBean;
import org.apache.ws.security.saml.ext.builder.SAML2Constants;
import org.opensaml.common.SAMLVersion;

/**
 *  Callback handler that populates a SAML 2.0 assertion based on the SAML properties file
 */
public class SAMLCallbackHandler implements CallbackHandler {

    private String subjectName;
    private String subjectQualifier;
    private String confirmationMethod;

    public SAMLCallbackHandler()
    {
        subjectName = "AllowGreetingServices";
        subjectQualifier = "www.example.com";
        confirmationMethod = SAML2Constants.CONF_SENDER_VOUCHES;
    }

    public void handle(Callback[] callbacks)
            throws IOException, UnsupportedCallbackException
    {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof SAMLCallback) {
                SAMLCallback callback = (SAMLCallback) callbacks[i];
                callback.setSamlVersion(SAMLVersion.VERSION_20);
                SubjectBean subjectBean =
                        new SubjectBean(
                                subjectName, subjectQualifier, confirmationMethod
                        );
                callback.setSubject(subjectBean);
                createAndSetStatement(null, callback);
            } else {
                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
            }
        }
    }

    private void createAndSetStatement(SubjectBean subjectBean, SAMLCallback callback) {
        AuthenticationStatementBean authBean = new AuthenticationStatementBean();
        if (subjectBean != null) {
            authBean.setSubject(subjectBean);
        }
        authBean.setAuthenticationMethod("Password");
        callback.setAuthenticationStatementData(Collections.singletonList(authBean));
    }

}

Refer to the Client-Side Flows section below for more details.

SignedSAMLTokenService Flow

Studio Visual Editor

signedSamlToken

Studio XML Editor or Standalone

<flow name="SignedSamlTokenServiceFlow" doc:name="SignedSamlTokenServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/signedsaml" exchange-pattern="request-response" doc:name="HTTP Inbound Endpoint"/>
        <cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure SAMLToken Signed service">
            <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>

Much the same as SAMLTokenService Flow, this flow uses SAMLTokenUnsigned action to validate SAML2 assertions. However, the action in this flow uses a digital signature to verify the trustworthiness of the original authenticator. To validate the digital signature on the message, the CXF component uses a keystore specified in the signaturePropFile. (Refer to UsernameTokenEncryptedService Flow section above for more information on verifying digital signatures.)

When an end user submits a samlTokenSigned salutation request, the Web service client sends a SOAP request message (see below) to the SignedSAMLTokenService flow in the WS-security application.

SOAP Request Message:
<soap:Header>
        <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="1">
            <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="CertId-E847A979F41D3E8185134621375247815">
                MIICGDCCAYECBEs5ItowDQYJKoZIhvcNAQEEBQAwUzELMAkGA1UEBhMCVVMxDDAKBgNVBAgTA2pvZTEMMAoGA1UEBxMDam9lMQwwCgYDVQQKEwNqb2UxDDAKBgNVBAsTA2pvZTEMMAoGA1UEAxMDam9lMB4XDTA5MTIyODIxMjc1NFoXDTI5MDIyNjIxMjc1NFowUzELMAkGA1UEBhMCVVMxDDAKBgNVBAgTA2pvZTEMMAoGA1UEBxMDam9lMQwwCgYDVQQKEwNqb2UxDDAKBgNVBAsTA2pvZTEMMAoGA1UEAxMDam9lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXTdHZyVwHGUTW3F0pLyP8dFT3b2ItMt1Nu5PKOmD0OmSBEZGmNRcZzYABWKnfJLVeBqr+At5mMYFqA4KX6W/WXnNDFz3xIgT5zjpcx3OIBStS/qbs3Qf7HbgEHAJce9qVHowB7vJP+dTsTJYCC7Zlpo/Uv4yl0oararXDI/S7QQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABLKNtAhloYg+YksqvMNToo1NwtE/k28314NKIGdxmFn+baCV20zvtRkmHCDL5HO4lGTePze3btNdScUiLmUKIlMRSRIVxLMC6dmkzdlfCIg4+qvsAxQO23LIeOhujP2iqcHyD9GTUgL47hu9UJOu1Fk9ZnCHsK+LsbHogv5UrcI
            </wsse:BinarySecurityToken>
            <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             ID="_E847A979F41D3E8185134621375247212" IssueInstant="2012-08-29T04:15:52.472Z"
                             Version="2.0" xsi:type="saml2:AssertionType">
                <saml2:Issuer>self</saml2:Issuer>
                <saml2:Subject>
                    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
                                  NameQualifier="www.example.com">AllowGreetingServices
                    </saml2:NameID>
                    <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"/>
                </saml2:Subject>
                <saml2:Conditions NotBefore="2012-08-29T04:15:52.472Z" NotOnOrAfter="2012-08-29T04:20:52.472Z"/>
                <saml2:AuthnStatement>
                    <saml2:AuthnContext>
                        <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password
                        </saml2:AuthnContextClassRef>
                    </saml2:AuthnContext>
                </saml2:AuthnStatement>
            </saml2:Assertion>
            <wsse:SecurityTokenReference
                    xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
                    wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
                    wsu:Id="STRSAMLId-E847A979F41D3E8185134621375247816">
                <wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">
                    _E847A979F41D3E8185134621375247212
                </wsse:KeyIdentifier>
            </wsse:SecurityTokenReference>
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-18">
                <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="#id-17">
                        <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=""/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>l2yyoEpr7OkUX8J6RNTEPVjxAfU=</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI="#STRSAMLId-E847A979F41D3E8185134621375247816">
                        <ds:Transforms>
                            <ds:Transform
                                    Algorithm="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform">
                                <wsse:TransformationParameters>
                                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                                </wsse:TransformationParameters>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>rA4vUTJHRh5zS7XO/qzD6rdjG38=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>EGQFUSCuRgLPY7Mny5acRRadnRnxH+ZnF5fBsADfsA+G/qG4ZxCUVRSyvbJ6D53IDAZ0JnEq2wzt
                    bGaHWDdI/R20fACt1Q7bUBAIRXFHXrYNjGWEBu6Dw9pmxz9GF1OO0VzvSCWRkpiMWGCfmVFdz4Hn
                    gq6PUghSBHwD2dfP7fk=
                </ds:SignatureValue>
                <ds:KeyInfo Id="KeyId-E847A979F41D3E8185134621375247813">
                    <wsse:SecurityTokenReference wsu:Id="STRId-E847A979F41D3E8185134621375247814">
                        <wsse:Reference URI="#CertId-E847A979F41D3E8185134621375247815"
                                        ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
        </wsse:Security>
</soap:Header>

Where the SAMLTokenService flow processed unsigned messages — messages which without a digital signature from the original authenticator in the SOAP header — this flow processes signed messages.

Studio Visual Editor

signature

Studio XML or Standalone

<cxf:jaxws-service serviceClass="com.mulesoft.mule.example.security.Greeter" doc:name="Secure SAMLToken Signed service">
            <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>

As with the SAMLTokenService Flow, the CXF component delegates SAML Token validation to the SAML2 Token Validator. The token validator, in turn, references a custom SAML2 token validator. The samlCustomValidator uses a Java class to confirm the contents of the SAML subject are correct. Additionally, this CXF component validates the digital signature of the message’s original authenticator against a keystore in the wssecurity.properties file.

Client-Side Flows

This example application includes client side configurations which enable the application to function. The service-clients flow in the WS-Security application consists of a flow and several subflows which facilitate client-side submissions to the server side.

client-server_diagram

Double-click the service-clients.mflow file in the package explorer to open the service-clients configuration in a separate tab in Anypoint Studio.

The client-side subflows contain different kinds of client security information which enables Mule to successfully process requests on the server side. For example, the client-side usernameToken subflow contains the end user security information against which the server-side UsernameTokenService validates the message. It sets the UsernameToken and Timestamp actions, provides the user, and relies on a password callback class (see below) to provide the user password.

Callback Class:
public class PasswordCallback implements CallbackHandler
{
    public void handle(Callback[] callbacks)
    {
        ...cut...
        if (pc.getIdentifier().equals("joe"))
        {
            pc.setPassword("secret");
        }
    ...

Without client-side services, there would be no mechanism for submitting requests to the server-side of the example application. Ergo, these client-side services exist to simulate the various real-life requests that end users might submit to a Web service.

Client-Side XML:
<?xml version="1.0" encoding="UTF-8"?>
<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:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" 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  http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd ">
    <spring:beans>
        <spring:bean class="com.mulesoft.mule.example.security.SAMLCallbackHandler" id="samlCallbackHandler" name="samlCallbackHandler"/>
    </spring:beans>
    <flow doc:name="SecurityClients" name="SecurityClients">
        <http:inbound-endpoint doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response" host="localhost" path="client" port="63080"/>
        <set-payload doc:name="Set payload with 'name' query param" value="#[message.inboundProperties.'http.query.params'.name]"/>
        <set-variable doc:name="Set clientType" value="#[message.inboundProperties.'http.query.params'.clientType]" variableName="clientType"/>
        <choice doc:name="Choice">
            <when expression="#[clientType == 'unsecure']">
                <flow-ref doc:name="Invoke unsecure sub-flow" name="unsecure"/>
            </when>
            <when expression="#[clientType == 'usernameToken']">
                <flow-ref doc:name="Invoke usernameToken sub-flow" name="usernameToken"/>
            </when>
            <when expression="#[clientType == 'usernameTokenSigned']">
                <flow-ref doc:name="Invoke usernameToken Signed sub-flow" name="usernameTokenSigned"/>
            </when>
            <when expression="#[clientType == 'usernameTokenEncrypted']">
                <flow-ref doc:name="Invoke usernameToken Encrypted sub-flow" name="usernameTokenEncrypted"/>
            </when>
            <when expression="#[clientType == 'samlToken']">
                <flow-ref doc:name="Invoke samlToken sub-flow" name="samlToken"/>
            </when>
            <when expression="#[clientType == 'samlTokenSigned']">
                <flow-ref doc:name="Invoke samlToken Signed sub-flow" name="samlTokenSigned"/>
            </when>
            <otherwise>
                <set-payload doc:name="Client type is not supported" value="Client type is not supported"/>
            </otherwise>
        </choice>
        <set-property doc:name="Set response Content-Type" propertyName="Content-Type" value="text/plain"/>
        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <set-payload doc:name="Set Payload" value="There has been an Error processing the request"/>
            <set-property doc:name="Set response Content-Type" propertyName="Content-Type" value="text/plain"/>
        </catch-exception-strategy>
    </flow>
    <sub-flow doc:name="unsecure" name="unsecure">
        <cxf:jaxws-client doc:description="Unsecure SOAP client" doc:name="Unsecure SOAP client" operation="greet" serviceClass="com.mulesoft.mule.example.security.Greeter"/>
        <http:outbound-endpoint doc:name="Invoke unsecure Web Service" exchange-pattern="request-response" host="localhost" path="services/unsecure" port="63081"/>
    </sub-flow>
    <sub-flow doc:name="usernameToken" name="usernameToken">
        <cxf:jaxws-client doc:name="UsernameToken SOAP client" operation="greet" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="UsernameToken Timestamp"/>
                    <cxf:property key="user" value="joe"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-client>
        <http:outbound-endpoint doc:name="Invoke usernameToken Web Service" exchange-pattern="request-response" host="localhost" path="services/username" port="63081"/>
    </sub-flow>
    <sub-flow doc:name="usernameTokenSigned" name="usernameTokenSigned">
        <cxf:jaxws-client doc:name="UsernameToken Signed SOAP client" operation="greet" 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="user" value="joe"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-client>
        <http:outbound-endpoint doc:name="Invoke usernameToken Signed Web Service" exchange-pattern="request-response" host="localhost" path="services/signed" port="63081"/>
    </sub-flow>
    <sub-flow doc:name="usernameTokenEncrypted" name="usernameTokenEncrypted">
        <cxf:jaxws-client doc:name="UsernameToken Encrypted SOAP client" operation="greet" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="UsernameToken Timestamp Encrypt"/>
                    <cxf:property key="encryptionPropFile" value="wssecurity.properties"/>
                    <cxf:property key="user" value="joe"/>
                    <cxf:property key="encryptionUser" value="joe"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-client>
        <http:outbound-endpoint doc:name="Invoke usernameToken Encrypted Web Service" exchange-pattern="request-response" host="localhost" path="services/encrypted" port="63081"/>
    </sub-flow>
    <sub-flow doc:name="samlToken" name="samlToken">
        <cxf:jaxws-client doc:name="SAMLToken SOAP client" operation="greet" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenUnsigned Timestamp"/>
                    <cxf:property key="samlPropFile" value="saml.properties"/>
                    <cxf:property key="samlCallbackClass" value="com.mulesoft.mule.example.security.SAMLCallbackHandler"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-client>
        <http:outbound-endpoint doc:name="Invoke SAMLToken Web Service" exchange-pattern="request-response" host="localhost" path="services/saml" port="63081"/>
    </sub-flow>
    <sub-flow doc:name="samlTokenSigned" name="samlTokenSigned">
        <cxf:jaxws-client doc:name="SAMLToken Signed SOAP client" operation="greet" serviceClass="com.mulesoft.mule.example.security.Greeter">
            <cxf:ws-security>
                <cxf:ws-config>
                    <cxf:property key="action" value="SAMLTokenSigned"/>
                    <cxf:property key="samlPropFile" value="saml.properties"/>
                    <cxf:property key="signatureKeyIdentifier" value="DirectReference"/>
                    <cxf:property key="user" value="joe"/>
                    <cxf:property key="passwordCallbackClass" value="com.mulesoft.mule.example.security.PasswordCallback"/>
                    <cxf:property key="samlCallbackClass" value="com.mulesoft.mule.example.security.SAMLCallbackHandler"/>
                </cxf:ws-config>
            </cxf:ws-security>
        </cxf:jaxws-client>
        <http:outbound-endpoint doc:name="Invoke SAMLToken Signed Web Service" exchange-pattern="request-response" host="localhost" path="services/signedsaml" port="63081"/>
    </sub-flow>
</mule>

Studio Visual Editor

ws security

Studio XML Editor

<?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>
    <flow doc:name="UnsecureServiceFlow" name="UnsecureServiceFlow">
        <http:inbound-endpoint address="http://localhost:63081/services/unsecure" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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:inbound-endpoint address="http://localhost:63081/services/username" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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:inbound-endpoint address="http://localhost:63081/services/signed" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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:inbound-endpoint address="http://localhost:63081/services/encrypted" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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:inbound-endpoint address="http://localhost:63081/services/saml" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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:inbound-endpoint address="http://localhost:63081/services/signedsaml" doc:name="HTTP Inbound Endpoint" exchange-pattern="request-response"/>
        <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>

Signature Key Identifier

Defines which key identifier type to use for signature. This is a String value and is specified with the XML signatureKeyIdentifier element. For more information on each value, see http://coheigea.blogspot.com/2013/03/signature-and-encryption-key.html.

Possible values are:

  • DirectReference

  • EmbeddedKeyName

  • EncryptedKeySHA1

  • IssuerSerial

  • SKIKeyIdentifier

  • Thumbprint

  • X509KeyIdentifier

See Also