Anypoint Enterprise Security Example Application
As a simple demo, this example application offers insights into how to use two Anypoint Enterprise Security features: Mule Digital Signature Processor and Mule Message Encryption Processor. The demo illustrates how to complete the following tasks with Mule:
-
Verify a digital signature
-
Encrypt part of a message payload
-
Decrypt a message payload
Assumptions
This document assumes that you are familiar with the Mule Studio Essentials guide. To increase your familiarity with Studio, consider completing the Basic Studio Tutorial.
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.
Importing the Application
-
Download the Anypoint Enterprise Security Example Application
-
Launch Mule Studio.
-
Under the File menu, select Import…
-
Studio opens an Import wizard. Expand the Mule folder in the wizard, and select Mule Studio generated Deployable Archive (.zip). Click Next.
If your operating system automatically unzipped the application, select Mule Studio Project from External Location instead of Mule Studio generated Deployable Archive (.zip). -
Use the epllipsis button (…) next to the Zip File field to browse for, then select, the Mule application you downloaded:
anypoint_enterprise_security_example.zip
. -
Click Finish. Studio imports then opens the project.
Setting Up, Then Running the Application
-
In the anypoint_enterprise_security_example project, scroll down the Studio canvas to the Get_secret_file flow.
-
Double-click the Groovy component to open its Pattern Properties panel.
-
In the Script Text field, adjust the filepath of the
encrypted.txt
file to match your system’s filepath, then click OK to save your change. -
Click the Save icon in Studio to save the project.
-
In the Package Explorer, right-click the project name, then select Run As > Mule Application.
-
Mule runs the application. In the console, it displays the following message:
Started anypoint_enterprise_security_example app
.
How it Works
The Encrypted Message Producer application consists of three simple [flows], each of which acts as a Web service provider which encrypts and decrypts a message before returning a response to the caller. Organized according to function, these flows serve different purposes within the application.
-
Get_CC_information receives Web service requests for a customer’s credit card information, which it retrieves, encrypts, then returns to the caller (See image below, top).
-
Decrypt_The_Request decrypts messages it receives logs the decryption activity, then returns the unencrypted message contents - in this case, credit card information - to the caller. (See image below, middle).
-
Get_secret_file decrypts, upon request, the contents of a file, then returns a response to the caller that displays the decrypted contents of the file. (See image below, bottom).
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:secure-property-placeholder="http://www.mulesoft.org/schema/mule/secure-property-placeholder"
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:encryption="http://www.mulesoft.org/schema/mule/encryption"
xmlns:signature="http://www.mulesoft.org/schema/mule/signature"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
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/signature http://www.mulesoft.org/schema/mule/signature/current/mule-signature.xsd
http://www.mulesoft.org/schema/mule/encryption http://www.mulesoft.org/schema/mule/encryption/current/mule-encryption.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/secure-property-placeholder http://www.mulesoft.org/schema/mule/secure-property-placeholder/current/mule-secure-property-placeholder.xsd">
<signature:config name="Signature" enableLanguage="true" doc:name="Signature">
<signature:jce-signer-config algorithm="HmacMD5" key="JLfl5sER3kt4oVkzP2d39UQrUxrEK63LjmXAO45b6cU=" />
</signature:config>
<encryption:config name="plainXml" doc:name="Encryption" enableLanguage="true">
<encryption:xml-encrypter-config algorithm="AES_128" key="pNVDBAtJ8S8mXfHc" xpath="/user/cc" />
</encryption:config>
<encryption:config name="e" enableLanguage="true" doc:name="Encryption">
<encryption:jce-encrypter-config algorithm="CAST5" key="poso123456789lal" />
</encryption:config>
<encryption:config name="symmetricPlain" doc:name="Encryption">
<encryption:jce-encrypter-config key="${xml.encrypter.key}" />
</encryption:config>
<encryption:config name="Encryption" doc:name="Encryption" />
<flow name="Get_CC_information" doc:name="Get_CC_information">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" />
<expression-filter
expression="#[message.inboundProperties['token'] != null && message.inboundProperties['user'] !=null ]"
doc:name="Expression" />
<signature:verify-signature config-ref="Signature"
input-ref="#[message.inboundProperties['user']]" expectedSignature="#[message.inboundProperties['token']]"
doc:name="Verify User Signature"
doc:description="Verify if the Signature is correct, so we can validate the User" />
<set-payload
value="#[new String("<user><name>Royal Bank of Canada</name><id>Royal_Bank_Of_Canada</id><cc><company>Visa</company><number>1234567890</number><secret>123</secret></cc></user>")]"
doc:name="Create XML response based on User" />
<encryption:encrypt config-ref="plainXml"
doc:name="Encrypt the XML (only th CC Info)" using="XML_ENCRYPTER"
input-ref="#[payload.toString()]" />
</flow>
<flow name="Decrypt_The_Request" doc:name="Decrypt_The_Request">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081"
doc:name="HTTP" path="decrypt" />
<object-to-string-transformer doc:name="Object to String" />
<encryption:decrypt config-ref="plainXml" using="XML_ENCRYPTER" doc:name="Decrypt the xml payload" />
<logger level="INFO" message="#[new String(e.jce().encrypt(payload))]" doc:name="Log the return but encrypted" />
</flow>
<flow name="Get_secret_file" doc:name="Get_secret_file">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081"
doc:name="HTTP" path="getFile" />
<expression-filter
expression="#[message.inboundProperties['token'] != null && message.inboundProperties['user'] !=null ]"
doc:name="Expression" />
<signature:verify-signature config-ref="Signature"
input-ref="#[message.inboundProperties['user']]" expectedSignature="#[message.inboundProperties['token']]"
doc:name="Verify User Signature"
doc:description="Verify if the Signature is correct, so we can validate the User" />
<scripting:component doc:name="Look for Encrypted Message">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[return new FileInputStream('src/test/resources/encrypted.txt');]]></scripting:text>
</scripting:script>
</scripting:component>
<encryption:decrypt config-ref="symmetricPlain" doc:name="Decrypt Message" />
</flow>
</mule>
The sections below offer descriptions of the Anypoint Enterprise Security features' actions as each flow processes end user requests.
Get_CC_Information Flow
Requesting
From a browser, an end user submits a request via the URL to the Mule application to acquire a customer’s credit card information. To submit this request, open your browser and type the following in the address bar:
http://localhost:8081/?user=Royal_Bank_of_Canada&token=z/TKVFswDDOQw2kjW9Y4jQ==
Processing
Upon receipt of an HTTP request, this flow uses a Mule Digital Signature Processor to verify the identity of the message’s sender. Mule evaluates the token it receives as a parameter of the request (that is, the token in the URL of the request). The table below describes the configurations of the Digital Signature Processor.
Config Reference |
References the Signature global digital signature element. |
Operation |
Indicates that the element verifies a signature, rather than apply a signature. |
Input Reference |
Uses a Mule Expression to define the part of the payload to which the digital signature applies. |
Expected Signature |
Uses a Mule Expression to define the parameter Mule uses to verify the signature. |
<signature:verify-signature config-ref="Signature" input-ref="#[message.inboundProperties['user']]" expectedSignature="#[message.inboundProperties['token']]" doc:name="Verify User Signature" doc:description="Verify if the Signature is correct, so we can validate the User"/>
What is Global Element? Mule ESB uses Global Elements, like the Signature global element in this example, to specify transport details and set reusable configurations. Rather than repeatedly write the same code to apply the same configuration to multiple message processors, you can create one global element that details your configurations or transport details. Then, you can instruct any number of message processors in your Mule application to reference that global element. Learn more… In this example, the code which specifies the encryption strategy, the algorithm and the key does not exist within the Reservations flow; rather, that code resides in a global element at the top of the application’s XML configuration file (and in the Global Elements tab in Mule Studio — see image below). The Verify User Signature element in the Get_CC_Information flow references and uses the configurations defined within this global element (see code in expandable section below). |
The XML for Global Signature Element
<signature:config name="Signature" enableLanguage="true" doc:name="Signature">
<signature:jce-signer algorithm="HmacMD5" key="JLfl5sER3kt4oVkzP2d39UQrUxrEK63LjmXAO45b6cU="/>
</signature:config>
After verifying that the requester is valid, Mule uses an expression to set the payload of the message to bank and credit card information. (This function is a simple way to simulate the action of retrieving a customer’s credit card information from a database. For practical reasons in this example, the credit card details are hard-coded into the application.)
Rather than returning the raw credit card information to the caller, Mule first encodes it using a Mule Message Encryption Processor. Using an XML encryption strategy, Mule encrypts the message payload. The table below describes the configurations of the encrypter.
Config Reference |
References the plainXML global encryption element |
Operation |
Indicates that the element encrypts, rather than decrypt a message |
Input Reference |
Instructs Mule to encrypt the payload and display as a string |
Using |
Indicates the encryption strategy |
<encryption:encrypt config-ref="plainXml" doc:name="Encrypt the XML (only th CC Info)" using="XML_ENCRYPTER" input-ref="#[payload.toString()]"/>
The Message Encryption Processor references the plainXML global encryption element to behave according to the following configurations:
-
Enable Language
-
key (that is, encryption key)
-
XPath expression which indicates the fields in the payload to encrypt
-
algorithm (that is, encryption algorithm)
<signature:config name="Signature" enableLanguage="true" doc:name="Signature">
<signature:jce-signer algorithm="HmacMD5" key="JLfl5sER3kt4oVkzP2d39UQrUxrEK63LjmXAO45b6cU="/>
</signature:config>
Decrypt_The_Request Flow
Requesting
An end user submits a request to the Mule application to decrypt the message payload in order to acquire a customer’s unencrypted credit card information. Use an HTTP Request tool (such as the REST Console plugin in the Chrome Web browser) to POST the request below to http://localhost:8081/decrypt
<?xml version="1.0" encoding="UTF-8"?>
<user><name>Royal Bank of Canada</name><id>Royal_Bank_Of_Canada</id><cc><xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#kw-aes128" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/><xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:CipherValue xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">9eUu9/kVzwb4ExPxr2UTiugRKoU6oJE9</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:CipherValue xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">cUmSEUP5M/OJsIS9MQvX3tMPBk9MgEo1yu2yGDc8swPVuTcs67nwFi25Yak86v+21I1Y98amjseX
5jU4hTz3eJXqd3AVkvTsWA/3d79yoY/c1CyOiTenlSw38+kHQ+JR</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></cc></user>
Processing
After accepting an HTTP request from and end user, Mule converts the message payload from a Java object to a string, then employs a Mule Message Encryption Processor to decrypt the message payload.
Using an XML encryption strategy, Mule decrypts the message payload before logging the decryption activity. Mule then returns a response to the caller, which contains the unencrypted credit card data. The table below describes the configurations of the decrypter.
Config Reference |
References the plainXML global encryption element |
Operation |
Indicates that the element encrypts, rather than decrypt a message |
Encrypter to use |
Indicates the encryption strategy |
<encryption:decrypt config-ref="plainXml" using="XML_ENCRYPTER" doc:name="Decrypt the xml payload"/>
The Message Encryption Processor references the plainXML globabl encryption element to behave according to the following configurations:
-
Enable Langugage
-
key (that is, encryption key)
-
XPath expression which indicates the fields in the payload to decrypt
-
algorithm (that is, encryption algorithm)
Responding
Finally, Mule uses the HTTP endpoint to pass the response - decrypted credit card information - to end user’s browser. The code below displays the unencrypted credit card information.
<?xml version="1.0" encoding="UTF-8"?><user><name>Royal Bank of Canada</name><id>Royal_Bank_Of_Canada</id><cc><company>Visa</company><number>1234567890</number><secret>123</secret></cc></user>
Get_secret_file Flow
Requesting
From a browser, an end user submits a request via the URL to the Mule application to decrypt the contents of a particular file, then displays the decrypted content to the users. To submit this request, open your browser and type the following in the address bar:
http://localhost:8081/getFile?user=Royal_Bank_of_Canada&token=z/TKVFswDDOQw2kjW9Y4jQ==
Processing
Upon receipt of an HTTP request, this flow, in a manner very similar to the Get_CC_Information flow, uses a Mule Digital Signature Processor to verify the identity of the message’s sender.
Next, Mule uses a Groovy script to locate the file that contains the data to decrypt (in this case the encryption.txt
file in the src > test > resources
folder). It then passes the file content to the Mule Message Encryption Processor to decrypt.
The processor references the symmetricPlain global encryption element for directions on how to decrypt the file’s contents. The symmetricPlain element uses the JCE encryption strategy (as indicated by the BINARY_ENCRYPTER
selection in the Default field), provides the encryption key, and defines the encryption algorithm.
See Also
-
For more information on encryption in Mule, refers to Mule Message Encryption Processor.
-
For more information on signatures in Mule, refer to Mule Digital Signature Processor.