Mule allows us to expose services to the web through CXF, but what happens when these services handle sensitive information that we don’t want just anybody to read or change? We need to be able to authenticate who is consuming the Web service and determine if the user should have access to the service or not.
In this post we are going to show you, step by step, how you can use the Username token profile to validate the user identity using a Spring Security authentication provider running in Mule.
To that end, Mule allows us to configure CXF with WS-Security.
What is WS-Security?
The WS-Security framework embeds existing security mechanisms into our SOAP message, thus leveraging existing protocols for messaging authentication, integrity and privacy, including, but not limited to mechanisms such as:
- X.509, which addresses authentication
- XML Signature, which covers the signing of messages
- XML Encryption, which describes ways of encrypting message content of a message
WS-Security also provides a mechanism for transferring simple user credentials via the UsernameToken element, thus keeping all security information in the SOAP part of the message. For more on WS-Security, consult Microsoft’s Understanding WS-Security.
How to enable WS-Security in Mule
The MuleSoft ESB documentation page Enabling WS-Security explains in detail how to configure a client and service to use WS-Security. On top of that, the WS-Security example describes the different security configuration options.
In this blog we are going to focus on the integration of CXF with the Spring Security Manager. As of Mule 3.1, you can use Spring Security 3.0 as a Security Manager inside of Mule. Furthermore, you can integrate this security provider with CXF to perform the UsernameToken authentication.
Our first task is to configure a security manager, as detailed in the following code snippet:
Next, we must enable WS-Security on our CXF Service. We do this via the CXF interceptors, WSS4J interceptor and the SAAJ interceptor. The first one performs security operations on the incoming SOAP message, relying on user-configured parameters, such as “action”, “user”, “passwordType” and “passwordCallbackRef”. For more on configuring the WSS4J interceptor, consult the Apache CXF WS-Security Web page.
The SAAJ interceptor facilitates the use of SAAJ, an in-memory DOM document format required by WSS4J.
The following code sample illustrates a security-enabled service configuration:
The example above sets the action to be UsernameToken and configures passwordCallbackRef, which references the CallbackHandler that’s responsible for providing the password for each identifier.
Here is an example of a password callback handler:
In this case though, where the security is provided by the Mule security manager, there is no need to implement our own callback handler; instead we reference the security manager. To do that, we simply declare the bean and reference it by the “passwordCallbackRef” in the WSS4J interceptor.
And that’s it. We’ve managed to set up the authentication on our services (or clients) by leveraging the Spring Security Manager in Mule.
Note that, while in this example we used an in memory authentication provider, there are more advanced security configurations that you could implement. For instance, a useful use case for an organization is to authenticate using LDAP, which is used as a central repository for user information and as an authentication service. It can also be used to store the role information for application users. To learn how to set the LDAP Security Provider in Mule click here.
Putting it all together
I implemented an example of a CXF secure proxy using the Spring Security Manager in Mule, you can download it and run the test to try it out: https://github.com/mulesoft/webservice-authentication-example.
Changes in Mule 3.3
We recently announced Mule 3.3 Milestone 1, where CXF has been upgraded, which in turn, upgrades the WSS4J version. This causes a backward compatibility issue involving previous versions of Mule integrating with the security manager. This is because validation is no longer performed in the callback Handlers but in the validators. A Validator describes a pluggable way of validating credentials that have been extracted by the processors. In Mule the validator responsible for integrating the Mule Spring Security Manager with CXF WS-Security is the MuleSecurityManagerValidator class.
As a result, there’s no need to set a callback handler anymore, but now we need the validator to bridge the service or client with the security manager:
For details on this validation issue, consult the Mule 3.3 migration guide .