On a recent client engagement we adopted SOAP over HTTP as our preferred communication channel for Web Service consumers. Since the transport protocol was HTTP, our next requirement was to setup HTTP Basic Authentication and role-based authorization. We tend to prefer simpler transport-level authentication over WS-Security which is overkill for most situations.
We had a look at a couple of approaches which are available in the Mule ecosystem:
We found option #2 be a much more powerful approach because you could seamlessly swap the existing security manager with a custom implementation without much effort (for example, you could swap generic LDAP Authentication with DAO-based authentication logic).
Spring Security in Mule
Currently the Spring Security 3.0 library offers 4 different provider mechanisms eg. JAAS, LDAP, CAS and DAO. Given our clients tight integration with LDAP we chose LDAP as our security provider.
If you’ve opted for Maven as your project management tool, start by adding the required dependencies. These artifacts usually are:
- security-api (Mule Module)
- spring-security-core (version - 3.1.0.RELEASE)
- spring-security-ldap (version - 3.1.0.RELEASE)
- spring-ldap-core(version - 1.3.1.RELEASE)
Now add a Mule Security Manager and bind it to a Security provider to your configuration xml, something like this:
(Do ensure you add appropriate namespace references to your config xml)
Welcome to the (Spring Security) Zoo
Mule allows you to have several Security Providers as part of your Mule Security Managercontext definition. Each Security Manager is associated with an Authentication Providerusing the
delegate-ref attribute. In a nutshell, an Authentication Provider is a wrapper for providing authentication services. For example,
org.springframework.security.authentication.dao.DaoAuthenticationProvider is the class which retrieves user details from a simple UserDetails Service (often backed by a properties file containing users and groups).
All these security-related objects exist in a hierarchy as follows:
Mule Security Manager -> Spring Security Provider -> Ldap Authentication Provider -> Ldap Server Definition
LDAP as a Spring Security Provider
Assuming you’ve opted for LDAP as your security provider, you need to declare a Spring bean with the Ldap Server definition, then Now attach this bean to the Authentication Provider via the
server-ref attribute. e.g.
ldap-authentication-provider attributes are generic values so take them with a grain of salt as will change per organization (particularly if your LDAP server is Microsoft ActiveDirectory).
Occasionally during Unit Testing you might not have access to a live LDAP instance. We adopted the following approach to overcome such issues.
Since the Mule Security Manager supports multiple Security providers, you could embed a separate provider just for unit testing. This additional provider could be a simple DaoAuthenticationProvider. e.g.
HTTP Authentication in Mule
At this stage the Security Provider is ready to go. Inject it in your “http-inbound-endpoint” e.g.
The key addition is the
http-security-filter element nested inside the
http:inbound-endpoint. This ensures that Mule responds with the correct 401/403 HTTP error codes to prompt the client to authenticate. (Note nested filters aren’t supported in AnyPoint Studio’s graphical flow editor - you’ll need to edit the flow XML directly.)
This only provides authentication and no authorization. If you need role-based authorization, add an
authorization-filter to your http-inbound-endpoint. e.g.
Note, the usage of the securityProviders attribute here. While unit testing, you could point to a User Service DAO based provider (which allows all uses with id “FOO” and pwd “BAR”) but if you wish to connect to a real LDAP instance, swap this for the ”SpringSecurityProvider” bean (which connects to an LDAP instance).
This is all you need to setup HTTP Basic Authentication and role-based authorization.
Programmatic Access to Identity Info
However, there are instances where you need to include some additional business logic like returning filtered response data for all users belonging to a particular role.
In such cases, you can create a Java component and get access to the Mule Security Context to gather the ACL metadata. Here is a Mule custom component which helps you achieve this.
By delegating security concerns to the Spring Security framework, Mule allows a lot of flexibility in separating where identity information comes from vs where security checks are applied. Additionally you can easily access the identity information of an authenticated consumer programmatically to implement custom security behaviour.