SOAP Web Service Security Example
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 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.
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.
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 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.
Set Up and Run the Example
As with this WS-Security example, you can create template applications straight out of the box in Mule 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 in Mule ESB.
-
Create, then run the example application in Mule Studio.
-
Open your Web browser.
-
In the address bar, type
localhost:63080/client?clientType=unsecure&name=John
-
Press enter to elicit a response from the WS-Security application (see image below).
-
Adjust the URL to change the name from
John
to your name, then press enter to elicit a new response from the application. -
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
-
-
Press enter to elicit a new response from the application (see example, below).
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.
-
Complete the procedure to create, then run the Security template in Mule Studio, or the Security example in Mule Standalone (Mule ESB without Studio).
-
In the Package Explorer, navigate to
src/main/java
, then expand thecom.mulesoft.mule.example.security
folder to reveal theSecureClient
file. -
Right click the
SecureClient
file, then select Run As > Java Application. -
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[] -
Click below the last line in the list,
q. Quit
, to activate your cursor in the console pane. -
Below the last line, type
2
, then press enter to submit a request with Username Token security to the WS-Security application. -
Mule processes the request and returns a response in the console pane which reads,
Hello Mule
. -
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.
-
Mule processes the request and returns a response in the console pane which reads,
Hello Mule
. -
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
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 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.
Studio Visual Editor
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 Mule Studio, navigate to the source file in the Package Explorer. Find the Java
|
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
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.
View the 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 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
Studio Visual Editor
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
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.
View the 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 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.
Studio Visual Editor
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.
|
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
<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.
The 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 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.