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 security filter:
This component can be downloaded from exchange or from the Mule palette in Anypoint Studio.
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