WSO2 ESB comes with a rich collection of useful mediators to filter, transform, route and manipulate messages. Developers can use these custom mediators to very easily add extra functionality. AuthenticationMediator is a custom mediator that can authorize users to access a Web service based on HTTP Basic authentication.
Introduction
AuthenticationMediator employs WSO2 UserManager to authenticate users. UserManager realms have the ability to connect new or existing user stores maintained in different technologies such as LDAP, Acegi or relational databases.
Features of AuthenticationMediator
- Clients provide username/password using HTTP Basic authentication
- Can authenticate users against user stores maintained in either LDAP, Acegi or RDBMS
Applies To
| WSO2 ESB version | 1.5 |
| WSO2 UserManager | version 0.5 |
| Axis2 | 1.3 |
Table of contents
This tutorial shows how to install and run AuthenticationMediator, then it goes on to explain implementation details of the Mediator. If you are only interested in implementation details then you can jump to it straight away.
- Background [0]
- Installing and Running AuthenticationMediator [0]
- Connecting to a RDBMS User Store [0]
- Connecting to a LDAP User Store [0]
- Connecting to a Acegi user store [0]
- Implementing the AuthenticationMediator [0]
- Conclusion [0]
authentication-mediator.zip [1] from this page and extract it inside the <esb-home> directory. Make sure it isn't extracted to a sub directory, as the directory "authentication-mediator" must be directly under <esb-home>.
here [2] and unzip it. We will call this folder <acegi-home>
- here [3] - Mediator, Factory and Serializer.
When mediator() method of AuthenticationMediator is called, it reads username/password from HTTP headers and the authenticate() method of the realm is called to provide authentication. If the user is not authenticated, an exception is thrown and the service will not be accessible.
Axis2MessageContext axis2smc = (Axis2MessageContext) synCtx;
org.apache.axis2.context.MessageContext axis2MessageCtx =
axis2smc.getAxis2MessageContext();
Map tmp = (Map)axis2MessageCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
String authString = (String)tmp.get("Authorization");
String username = null;
String password = null;
if (authString != null) {
authString = authString.trim();
}
if (authString.startsWith("Basic ")) {
authString = new String(Base64.decode(authString.substring(6)));
int i = authString.indexOf(':');
if (i == -1) {
username = authString;
} else {
username = authString.substring(0, i);
}
if (i != -1) {
password = authString.substring(i + 1);
if (password != null && password.equals("")) {
password = null;
}
}
}
if(!realm.getAuthenticator().authenticate(username, password)){
handleException("Invalid Username/Password!", synCtx);
}
When the createMediator() method of the AuthenticationMediatorFactory is called, the Realm is created and set to the AuthenticationMediator.
Class clazz = Class.forName(realmClassName);
Realm realm = (Realm) clazz.newInstance();
Object configBean = realm.getRealmConfiguration();
.................
/*
Populate configBean by reading name-value pairs given
by parameter elements inside the <userStore>
of the Synapse Configuration.
Using Java Reflection.
*/
........
...
realm.init(configBean);
AuthenticationMediator mediator = new AuthenticationMediator();
mediator.setRealm(realm);
return mediator;
The XML snippet given in the Synapse definition is used for creating and configuring the Realm inside the Mediator Factory. Since Java Reflection is used for populating the configuration of the Realm, any custom Realm can be loaded into the AuthenticationMediator.
For example,
<syn:userStore>
<syn:realmClass>org.wso2.usermanager.custom.jdbc.JDBCRealm</syn:realmClass>
<syn:realmParameters>
<syn:parameter name="UserTable">users</syn:parameter>
</syn:realmParameters>
</syn:userStore>
The method called for the above parameter is setUserTable() in the configBean of the Realm.
Conclusion
WSO2 ESB is a powerful and extensible enterprise service bus. UserManager is a flexible and extensible library that can be configured to connect user stores belonging to different technologies. In the same way, developers can add functionality to the WSO2 ESB by writing Mediators. New Realms can be written enabling UserManager to connect to many different types of user stores. AuthenticationMediator uses Java Reflection technology to populate realms by reading the XML snippet. Therefore, AuthenticationMediator is not restricted to the Realms mentioned above.
Author
Dimuthu Leelarathne is a Senior Software Engineer at WSO2. She is a committer of the Apache Software Foundation.
dimuthul at wso2 dot com
- here [3] - Mediator, Factory and Serializer.
When mediator() method of AuthenticationMediator is called, it reads username/password from HTTP headers and the authenticate() method of the realm is called to provide authentication. If the user is not authenticated, an exception is thrown and the service will not be accessible.
Axis2MessageContext axis2smc = (Axis2MessageContext) synCtx; org.apache.axis2.context.MessageContext axis2MessageCtx = axis2smc.getAxis2MessageContext(); Map tmp = (Map)axis2MessageCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS); String authString = (String)tmp.get("Authorization"); String username = null; String password = null; if (authString != null) { authString = authString.trim(); } if (authString.startsWith("Basic ")) { authString = new String(Base64.decode(authString.substring(6))); int i = authString.indexOf(':'); if (i == -1) { username = authString; } else { username = authString.substring(0, i); } if (i != -1) { password = authString.substring(i + 1); if (password != null && password.equals("")) { password = null; } } } if(!realm.getAuthenticator().authenticate(username, password)){ handleException("Invalid Username/Password!", synCtx); }When the createMediator() method of the AuthenticationMediatorFactory is called, the Realm is created and set to the AuthenticationMediator.
Class clazz = Class.forName(realmClassName); Realm realm = (Realm) clazz.newInstance(); Object configBean = realm.getRealmConfiguration(); ................. /* Populate configBean by reading name-value pairs given by parameter elements inside the <userStore> of the Synapse Configuration. Using Java Reflection. */ ........ ... realm.init(configBean); AuthenticationMediator mediator = new AuthenticationMediator(); mediator.setRealm(realm); return mediator;The XML snippet given in the Synapse definition is used for creating and configuring the Realm inside the Mediator Factory. Since Java Reflection is used for populating the configuration of the Realm, any custom Realm can be loaded into the AuthenticationMediator.
For example,
<syn:userStore> <syn:realmClass>org.wso2.usermanager.custom.jdbc.JDBCRealm</syn:realmClass> <syn:realmParameters> <syn:parameter name="UserTable">users</syn:parameter> </syn:realmParameters> </syn:userStore>The method called for the above parameter is setUserTable() in the configBean of the Realm.
Conclusion
WSO2 ESB is a powerful and extensible enterprise service bus. UserManager is a flexible and extensible library that can be configured to connect user stores belonging to different technologies. In the same way, developers can add functionality to the WSO2 ESB by writing Mediators. New Realms can be written enabling UserManager to connect to many different types of user stores. AuthenticationMediator uses Java Reflection technology to populate realms by reading the XML snippet. Therefore, AuthenticationMediator is not restricted to the Realms mentioned above.
Author
Dimuthu Leelarathne is a Senior Software Engineer at WSO2. She is a committer of the Apache Software Foundation.
dimuthul at wso2 dot com