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. But 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 some 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 GET request.
Welcome to CORS.
Cross-origin resource sharing (CORS) is a defense mechanism that restricts the resources (e.g. fonts, AJAX calls, etc.) from being requested from another domain outside the domain from which the resource originated.

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 you global elements in 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.
<mule xmlns: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/encryption http://www.mulesoft.org/schema/mule/encryption/current/mule-encryption.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/cors classpath:/mule-cors.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-current.xsd">
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:

<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 CORS policy on your API endpoint.
More more complete information, check out Mule’s documentation on CORS.
I hope iI 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.
