Add security with Spring Security Filter in MuleSoft 4

  • September 16, 2020

Security is of foremost importance in any web application. MuleSoft provides an array of security implementation features ranging from security established with configuring individual message processors to securing the environment as a whole.

Generally, API Manager is the way to implement various security measures and policies to an application. The API manager is solely responsible for the implementation of such policies, but it often comes at a price, which may be considered overhead for clients.

This technical article deals with the imposing security issue, sans the API Manager, using Spring.

Spring Security

The Spring module enables Mule apps to use the Spring framework.

Add Spring module to your project

In Anypoint Studio 7, Spring module is provided in the default configuration.

In Mule Palette, search for “Spring” and drag the Authorization Filter operation to the Studio canvas.

If you are coding a project using only XML, add the Spring module to your application from the palette, or add the following dependency in your pom.xml file:

<dependency>
  <groupId>org.mule.modules</groupId>
  <artifactId>mule-spring-module</artifactId>
  <version>RELEASE</version>
  <classifier>mule-plugin</classifier>
</dependency>

Mule runtime engine (Mule) automatically substitutes the latest version for the RELEASE keyword.

Spring module 1.3.0 requires Mule 4.1.1 and later. You can find the dependencies for earlier versions in Exchange by selecting a version and clicking Dependency Snippets.

Configure Spring Module

  • Add the following configuration:
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:spring="http://www.mulesoft.org/schema/mule/spring"
      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/core
        http://www.mulesoft.org/schema/mule/core/current/mule.xsd
        http://www.mulesoft.org/schema/mule/spring
        http://www.mulesoft.org/schema/mule/spring/current/mule-spring.xsd">

    <spring:config name="springConfig" files="beans.xml" />

</mule>
  • Put the beans.xml file in src/main/resources.

The Spring configuration must be valid. Here is an example beans.xml file:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xmlns:ss="http://www.springframework.org/schema/security"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/jdbc
	http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-4.2.xsd">
  <ss:authentication-manager alias="authenticationManager">
	<ss:authentication-provider>
  	<ss:user-service id="userService">
    	<ss:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN" />
    	<ss:user name="joe" password="{noop}secret" authorities="ROLE_ADMIN" />
    	<ss:user name="anon" password="{noop}anon" authorities="ROLE_ANON" />
    	<ss:user name="user" password="{noop}password" authorities="ROLE_ANON" />
    	<ss:user name="ross" password="{noop}ross" authorities="ROLE_ANON" />
    	<ss:user name="marie" password="{noop}marie" authorities="ROLE_ANON" />
  	</ss:user-service>
	</ss:authentication-provider>
  </ss:authentication-manager>
 

</beans>

Alternatively, these credentials could be stored in and fetched from a database rather than being stored in the same application.

If you’re using Anypoint Studio 7.2 or later, you don’t need to manually update the mule-artifact.json file.

Because Mule also needs a descriptor where the Spring beans are declared, the embedded packager within Studio automatically generates one with all the resources it picks up from the project. However, if you choose to declare the resources you need to export, then Studio packages only those resources.

The following example enables you to declare your beans.xml file in mule-artifact.json:

{
  "minMuleVersion": "4.3.0",
  "secureProperties": ["db.password","sf.password","sf.token","sf.consumer_secret","email.password","cloudhub.password"],
   "classLoaderModelLoaderDescriptor": {
    	"id": "mule",
    	"attributes": {
    	"exportedPackages":[
   "com.java.muleinuse"
   ],
        	"exportedResources": [
            	"beans.xml"
        	]
    	}
	}
}

Use Spring Security as a security manager

If you use Spring Framework 5.x with plain text passwords, you must prefix the password value with {noop}. For example, the password admin would be {noop}admin instead.

The Spring module supports the use of Spring security as a security manager in Mule apps. You must define an authentication manager in the Spring configuration file:

<ss:authentication-manager alias="authenticationManager">
	<ss:authentication-provider>
  	<ss:user-service id="userService">
    	<ss:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN" />
    	<ss:user name="joe" password="{noop}secret" authorities="ROLE_ADMIN" />
    	<ss:user name="anon" password="{noop}anon" authorities="ROLE_ANON" />
    	<ss:user name="user" password="{noop}password" authorities="ROLE_ANON" />
    	<ss:user name="ross" password="{noop}ross" authorities="ROLE_ANON" />
    	<ss:user name="marie" password="{noop}marie" authorities="ROLE_ANON" />
  	</ss:user-service>
	</ss:authentication-provider>
  	</ss:authentication-manager>

You can define a security manager within a Mule app that makes use of the Spring authentication manager like this:

<?xml version="1.0" encoding="UTF-8"?>
<mule
  xmlns:spring="http://www.mulesoft.org/schema/mule/spring"
  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.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-current.xsd
    http://www.mulesoft.org/schema/mule/core
    http://www.mulesoft.org/schema/mule/core/current/mule.xsd
    http://www.mulesoft.org/schema/mule/spring
    http://www.mulesoft.org/schema/mule/spring/current/mule-spring.xsd">

  <spring:config name="springConfig" files="beans.xml" />

  <spring:security-manager>
    <spring:delegate-security-provider
      name="memory-provider"
      delegate-ref="authenticationManager" />
  </spring:security-manager>

</mule>

Validate authentication with the Spring Authorization Filter

The Spring module adds support for a filter that fails if authentication cannot be validated using the Mule Security Manager:

?xml version="1.0" encoding="UTF-8"?>
<mule
  xmlns:http="http://www.mulesoft.org/schema/mule/http"
  xmlns:db="http://www.mulesoft.org/schema/mule/db"
  xmlns:spring="http://www.mulesoft.org/schema/mule/spring"
  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.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-current.xsd
    http://www.mulesoft.org/schema/mule/core
    http://www.mulesoft.org/schema/mule/core/current/mule.xsd
    http://www.mulesoft.org/schema/mule/spring
    http://www.mulesoft.org/schema/mule/spring/current/mule-spring.xsd
    http://www.mulesoft.org/schema/mule/db
    http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
    http://www.mulesoft.org/schema/mule/http
    http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">

  <spring:config name="springConfig" files="beans.xml" />

  <spring:security-manager>
    <spring:delegate-security-provider
      name="memory-provider"
      delegate-ref="authenticationManager" />
  </spring:security-manager>

  <http:listener-config
    name="HTTP_Listener_config"
     doc:name="HTTP Listener config"  >
      <http:listener-connection
        host="0.0.0.0"
        port="9090" />
  </http:listener-config>

  <flow name="spring-exampleFlow"  >
    <http:listener
      config-ref="HTTP_Listener_config"
      path="/"
      doc:name="Listener"  />
    <http:basic-security-filter
      realm="mule" />
      <spring:authorization-filter
        requiredAuthorities="ROLE_ADMIN" />
  </flow>
</mule>

Basic authentication flow using Spring Security

Basic authentication flow using Spring Security

Basic security filter:

This component can be downloaded from exchange or from the Mule palette in Anypoint Studio.

Basic security filter

Authorization filter:

Authorization filter

This uses all the above Spring libraries that can easily be added using Maven Central.

The http:basic-security-filter tries to authenticate the user using basic authentication. If the request is authenticated successfully, Mule retrieves the username and uses it in the Spring authorization-filter to search for that user and to try to authorize the request against the authority ROLE_ADMIN.

— By Shubhranshu