Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Achieving CORS in Mule ESB

DZone's Guide to

Achieving CORS in Mule ESB

Achieving CORS means you have a defense mechanism that restricts resources from being requested from another domain outside the domain from which the resource originated.

· Integration Zone
Free Resource

Migrating from On-Prem to Cloud Middleware? Here’s what Aberdeen Group says leading companies should be considering. Brought to you in partnershp with Liaison Technologies

So, you or your company has decided to write some APIs for your business or a product you are working on, and you used Mule ESB to write your HTTP endpoints (which can be called from others and consume your API). However, if you are not using Anypoint Manager to manage your APIs, then you might run into a problem.

After spending many tough hours on it, you are ready to test your first API. You get ready to call it using some client — maybe a SOAP or REST client. You press the button… and nothing happens. You start debugging your code, start checking all the connections and whatnot, and finally, you find that whatever endpoint you designed to expect a POST or GET or PUT or some other commonly used HTTP method is actually expecting “OPTIONS.” Now, what is this OPTIONS? Why is it being sent in spite of the fact that the AJAX call you made is clearly set up to send a POST or PUT request?

Welcome to CORS.

Cross-origin resource sharing (CORS) is a defense mechanism that restricts the resources (i.e., fonts, AJAX calls, etc.) from being requested from another domain outside the domain from which the resource originated.

screen-shot-2016-09-20-at-11-20-08-pm

A web page may freely embed images, stylesheets, scripts, iframes, videos, and some plugin content (such as Adobe Flash) from any other domain. However, embedded web fonts and AJAX (XMLHttpRequest) requests have traditionally been limited to accessing the same domain as the parent web page (as per the same-origin security policy). Cross-domain AJAX requests are forbidden by default because of their ability to perform advanced requests (POST, PUT, DELETE, and other types of HTTP requests, along with specifying custom HTTP headers) that introduce many cross-site scripting security issues.

CORS defines a way in which a browser and server can interact to determine safely whether or not to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests, but it’s more secure than simply allowing all cross-origin requests. It is a recommended standard of the W3C. For a complete explanation, please click here.

Let’s Make the API Accessible to All 

Today, I will show you how you can configure CORS on your APIs in Mule ESB, which is very simple. All we have to do is follow the few steps below.

Create a cors:config in your global elements in a mule-config file as follows.

<cors:config name="Cors_Configuration" doc:name="Cors Configuration">
	<cors:origins>
		<cors:origin url="*" accessControlMaxAge="30">
			<cors:methods>
				<cors:method>GET</cors:method>
				<cors:method>POST</cors:method>
				<cors:method>OPTIONS</cors:method>
			</cors:methods>
			<cors:headers>
				<cors:header>X-Allow-Origin</cors:header>
			</cors:headers>
		</cors:origin>
	</cors:origins>
</cors:config>

Add an XML namespace for cors:config in your Mule config file. I could not find an online resource, so I got the XSD and placed it in my Mule project’s resources folder, then added the namespace.

< mulexmlns: context = "http://www.springframework.org/schema/context"
xmlns: encryption = "http://www.mulesoft.org/schema/mule/encryption"
xmlns = "http://www.mulesoft.org/schema/mule/core"
xmlns: doc = "http://www.mulesoft.org/schema/mule/documentation"
xmlns: spring = "http://www.springframework.org/schema/beans"
xmlns: http = "http://www.mulesoft.org/schema/mule/http"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns: cors = "http://www.mulesoft.org/schema/mule/cors"
xsi: schemaLocation = "http://www.mulesoft.org/schema/mule/encryptionhttp://www.mulesof

Here is the complete mule-cors.xsd that you can keep in your resources folder:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
	xmlns:mule="http://www.mulesoft.org/schema/mule/core"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mulesoft.org/schema/mule/cors"
attributeFormDefault="unqualified" elementFormDefault="qualified">
	<xs:import namespace="http://www.w3.org/XML/1998/namespace"></xs:import>
	<xs:import namespace="http://www.springframework.org/schema/beans"
schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"></xs:import>
	<xs:import namespace="http://www.mulesoft.org/schema/mule/core"
schemaLocation="http://www.mulesoft.org/schema/mule/core/current/mule.xsd"></xs:import>
	<xs:element
		xmlns:mule="http://www.mulesoft.org/schema/mule/core"
substitutionGroup="mule:abstract-extension" name="config">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="mule:abstractExtensionType">
					<xs:annotation>
						<xs:documentation>Cors Module</xs:documentation>
					</xs:annotation>
					<xs:sequence>
						<xs:element minOccurs="0" maxOccurs="1" name="origins">
							<xs:annotation>
								<xs:documentation></xs:documentation>
							</xs:annotation>
							<xs:complexType>
								<xs:sequence>
									<xs:element minOccurs="0" maxOccurs="unbounded"
name="origin">
										<xs:complexType>
											<xs:complexContent>
												<xs:extension
													xmlns="http://www.mulesoft.org/schema/mule/cors"
base="OriginObjectType">
													<xs:attribute type="xs:string" use="optional"
name="value-ref"></xs:attribute>
												</xs:extension>
											</xs:complexContent>
										</xs:complexType>
									</xs:element>
								</xs:sequence>
								<xs:attribute type="xs:string" use="optional" name="ref">
									<xs:annotation>
										<xs:documentation>The reference object for this parameter</xs:documentation>
									</xs:annotation>
								</xs:attribute>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute type="xs:string" use="optional" name="name">
						<xs:annotation>
							<xs:documentation>Give a name to this configuration so it can be
later referenced by config-ref.</xs:documentation>
						</xs:annotation>
					</xs:attribute>
					<xs:attribute type="xs:string" use="optional" name="storePrefix">
						<xs:annotation>
							<xs:documentation>Prefix used to differentiate the object store
used as the backend of the configured origins.</xs:documentation>
						</xs:annotation>
					</xs:attribute>
					<xs:attribute type="xs:string" use="optional" name="originsStore-ref">
						<xs:annotation>
							<xs:documentation>The object store used for storing the origins.</xs:documentation>
						</xs:annotation>
					</xs:attribute>
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>
	<xs:complexType name="OriginObjectType">
		<xs:sequence>
			<xs:element minOccurs="0" maxOccurs="1" name="methods">
				<xs:annotation>
					<xs:documentation></xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:sequence>
						<xs:element minOccurs="0" maxOccurs="unbounded" name="method">
							<xs:complexType>
								<xs:simpleContent>
									<xs:extension base="xs:string">
										<xs:attribute type="xs:string" use="optional"
name="value-ref"></xs:attribute>
									</xs:extension>
								</xs:simpleContent>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute type="xs:string" use="optional" name="ref">
						<xs:annotation>
							<xs:documentation>The reference object for this parameter</xs:documentation>
						</xs:annotation>
					</xs:attribute>
				</xs:complexType>
			</xs:element>
			<xs:element minOccurs="0" maxOccurs="1" name="headers">
				<xs:annotation>
					<xs:documentation></xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:sequence>
						<xs:element minOccurs="0" maxOccurs="unbounded" name="header">
							<xs:complexType>
								<xs:simpleContent>
									<xs:extension base="xs:string">
										<xs:attribute type="xs:string" use="optional"
name="value-ref"></xs:attribute>
									</xs:extension>
								</xs:simpleContent>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute type="xs:string" use="optional" name="ref">
						<xs:annotation>
							<xs:documentation>The reference object for this parameter</xs:documentation>
						</xs:annotation>
					</xs:attribute>
				</xs:complexType>
			</xs:element>
			<xs:element minOccurs="0" maxOccurs="1" name="expose-headers">
				<xs:annotation>
					<xs:documentation></xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:sequence>
						<xs:element minOccurs="0" maxOccurs="unbounded" name="expose-header">
							<xs:complexType>
								<xs:simpleContent>
									<xs:extension base="xs:string">
										<xs:attribute type="xs:string" use="optional"
name="value-ref"></xs:attribute>
									</xs:extension>
								</xs:simpleContent>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute type="xs:string" use="optional" name="ref">
						<xs:annotation>
							<xs:documentation>The reference object for this parameter</xs:documentation>
						</xs:annotation>
					</xs:attribute>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute type="xs:string" use="optional" name="url">
			<xs:annotation>
				<xs:documentation></xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute
			xmlns="http://www.mulesoft.org/schema/mule/cors"
type="longType" use="optional" name="accessControlMaxAge">
			<xs:annotation>
				<xs:documentation></xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute type="xs:string" use="optional" name="ref">
			<xs:annotation>
				<xs:documentation>The reference object for this parameter</xs:documentation>
			</xs:annotation>
		</xs:attribute>
	</xs:complexType>
	<xs:element
		xmlns="http://www.mulesoft.org/schema/mule/cors"
		xmlns:mule="http://www.mulesoft.org/schema/mule/core" type="ValidateType"
substitutionGroup="mule:abstract-intercepting-message-processor" name="validate">
		<xs:annotation>
			<xs:documentation>Perform CORS validation. This operation will add
the necessary CORS headers to the response. If the request method is
OPTIONS it will not perform further processing of the message. If
this request is not a CORS request, then the processing will
continue without altering the message.</xs:documentation>
		</xs:annotation>
	</xs:element>
	<xs:complexType name="ValidateType">
		<xs:complexContent>
			<xs:extension
				xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:abstractInterceptingMessageProcessorType">
				<xs:attribute type="xs:string" use="optional" name="config-ref">
					<xs:annotation>
						<xs:documentation>Specify which configuration to use for this
invocation.</xs:documentation>
					</xs:annotation>
				</xs:attribute>
				<xs:attribute
					xmlns="http://www.mulesoft.org/schema/mule/cors"
type="booleanType" use="optional" default="false" name="publicResource">
					<xs:annotation>
						<xs:documentation>specifies if this resource should be publicly
available regardless the origin.</xs:documentation>
					</xs:annotation>
				</xs:attribute>
				<xs:attribute
					xmlns="http://www.mulesoft.org/schema/mule/cors"
type="booleanType" use="optional" default="false" name="acceptsCredentials">
					<xs:annotation>
						<xs:documentation>specifies whether the resource accepts
credentials or not.</xs:documentation>
					</xs:annotation>
				</xs:attribute>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:simpleType name="integerType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:integer"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="decimalType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:decimal"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="floatType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:float"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="doubleType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:double"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="dateTimeType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:dateTime"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="longType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:long"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="byteType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:byte"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="booleanType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:boolean"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="anyUriType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:anyURI"></xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
	<xs:simpleType name="charType">
		<xs:union>
			<xs:simpleType>
				<xs:restriction base="xs:string">
					<xs:minLength value="1"></xs:minLength>
					<xs:maxLength value="1"></xs:maxLength>
				</xs:restriction>
			</xs:simpleType>
			<xs:simpleType>
				<xs:restriction
					xmlns:mule="http://www.mulesoft.org/schema/mule/core"
base="mule:propertyPlaceholderType">
				</xs:restriction>
			</xs:simpleType>
		</xs:union>
	</xs:simpleType>
</xs:schema>

Now add cors:validate to your Mule flow:

screen-shot-2016-09-20-at-11-20-41-pm

<cors:validate config-ref="Cors_Configuration"
publicResource="true" acceptsCredentials="false" doc:name="CORS Validate" />         

That’s it! You are done! This is how we configure CORS in a Mule ESB on-premise API. If you use Anypoint API Manager, then configuring CORS is as easy as just clicking a button and applying the CORS policy on your API endpoint.

For more information, check out Mule’s documentation on CORS.

I hope I was able to give some concise steps that may help you to implement CORS in Mule ESB. Let me know if it helped you and if you found any problems with your implementation of CORS.

Is iPaaS solving the right problems? Not knowing the fundamental difference between iPaaS and iPaaS+ could cost you down the road. Brought to you in partnership with Liaison Technologies.

Topics:
mule esb ,integration ,cors ,tutorial ,api

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}