Contact Us 1-800-596-4880

WS-Security Example

Enterprise Edition

Version 3.3.1 only

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

When a Web service exposes private-network data to the outside world, that data travels through 4 - 7 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.

The WS-Security 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 submit his name, “John”, to one of the six variation, 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 will help 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.

Assumptions

This document describes the details of the example within the context of Mule Studio, Mule ESB’s graphical user interface (GUI). Where appropriate, the XML configuration follows the Studio interface screenshot in an expandable section.

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

Set Up

As with this WS-Security example, you can create template applications straight out of the box in Mule Studio or Mule Standalone (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 in Mule ESB.

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

  2. Open your Web browser.

  3. In the address bar, type

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

    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).

    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 Mule Studio.

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

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

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

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

    console1
  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.

    response
  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

The WS-Security 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.

For Mule Studio Users

In Mule Studio, double-click a building block to open its Properties Panel, then examine its configuration details. Alternatively, click the Configuration XML tab to examine the application’s XML configuration file.

config_tab-1

UnsecureService Flow

unsecure_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.

Two-Way vs. One-Way

Notice that the HTTP endpoint has a two-way message exchange pattern (as indicated by the small double-arrow icon — below, left). Because it must respond to the requester, the HTTP endpoint in this example has a request-response message exchange pattern.

If an HTTP endpoint has only to input information into an application, it requires a one-way message exchange pattern (below, right).

http_endpoints

A JAX-WS service, the SOAP 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 SOAP component processes all requests it receives.

no_security
<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 Mule Studio, navigate to the source file in the Package Explorer.

Find the Java:

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

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

    image::see-java.png[see_java]

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

  1. Navigate to the Mule Standalone folder on your local drive.

  2. Navigate to examples > security > src > main > java > com > mulesoft > mule > example > security.

  3. 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

usernameToken_flow

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.

Like the UnsecureService flow, this flow uses an HTTP endpoint to receive the request and a SOAP component to process the message. In this case, however, the SOAP 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

    usernameToken

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

uersnameTokenSigned

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.

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

usernameTokenSigned

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).

    see_java2

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).

keystore
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

UsernameTokenEncrypted

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.

In this flow, the SOAP 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.

decryption

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 SOAP Component in the client-side usernameTokenEncrypted subflow encrypts the body of the SOAP message (see image below).

double_click

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

SAMLTokenService Flow

samltoken_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.

In this flow, the SOAP component uses the Sender Vouches method to confirm the trustworthiness of the message sender. The SAMLTokenUnsigned Timestamp action ensures that the Web service will only process messages which contains a valid subject.

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

In this example, the SOAP 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.

validator_bean

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).

custom_validator

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 SOAP 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).

client_saml_config

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

SignedSAMLTokenService Flow

signedSAML_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 SOAP 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.

View the 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.

signature_component

As with the SAMLTokenService Flow, the SOAP 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 SOAP 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 Mule Studio (see image below).

service_clients_flow

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.

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