Tag Archives: AuthenticationProvider

ITIM Custom Authentication

ITIM allows you to provide your own custom authentication module which can be very useful to meet corporate authentication standards – such as authenticating with an authoritative LDAP, database or perhaps & more likely, AD.

ITIM ships with an example for a custom AD authentication provider in ${ITIM_HOME}/extensions/examples/authentication/adauthentication which is a really good place to start.

This shipped example covers enough about how to create the module so there is no need to repeat that here, but there are a couple of things that are worth pointing out to make things go a little better.

First of all, make sure your authentication factory matches the interface definition exactly;

public class ADProviderFactory implements
 AuthenticationProviderFactory {

 public ADProviderFactory() { }

 public AuthenticationProvider getProvider(Hashtable env)
 throws ConfigurationException {
 return (AuthenticationProvider)new ADAuthenticationProvider(env);
 }
}

I’ve added in the class cast to AuthenticationProvider from the example that’s shipped to ensure there is no chance that the caller thinks that we’re not meeting the interface – although it certainly does work without it.

Personally I found the example a useful base for the ADAuthenticationProvider and ADAuthenticationHelper classes, but feel free to add your own customisation in there as needed.  In particular in a large enterprise there can be issues for *nix based ITIM servers using the example’s way of determining the AD domain controller to connect to.   Windows based ITIM servers won’t have this problem (I’ll try to make that into another post).

In the design of your AuthenticationProvider class I’d suggest considering some of the following;

  • The AuthenticationProvider has to end up returning a SystemUser.  It should really check that the ITIM user that’s returned is active.  It wouldn’t be great to allow active AD users to login to their inactive ITIM admin accounts…..gulp!
  • There is no need to be exclusive about the authentication provider.  You can try AD, then maybe go off and try a database, and perhaps if none of that works trying the plain old ITIM login itself.  Also, consider adding properties to the enRoleADAuthentication.properties file to control which providers are active.
  • If you don’t mind a slight performance loss, move the loadProperties() call in the example into the authenticate method.  That way all your properties are dynamic and you don’t have to restart ITIM to pick up flag changes.
  • Be sure to add sufficient logging so you can see your module functioning.  Don’t over do it because although ITIM admins logging in won’t cause problems, if you have a lot of JNDI or web services happening then you may make your logs too noisy.  Also make sure you don’t do the usual security give-away’s by telling an attacker that an account name is wrong, or just the password was wrong – authentication failures should just state that the authentication failed – nothing more.
  • Don’t expose unnecessary details about your user repositories in the logs either.  Generic names should suffice so you can monitor progress.

 

When it comes to deployment there are a couple of points to add in;

  • First of all, put your new module in the classes directory of each of your WebSphere application servers.  So that’s /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/classes/ for a default install.  This is actually covered in an ISIM interim fix bit of doco update, but I’ve repeated it because it’s a pain to dig out the IV zip file just for that line.
  • Now, if you’re using a cluster you will also need to copy the jar into /opt/IBM/WebSphere/AppServer/profiles/DMgr/classes/.  If you don’t do this then you may see “class not found” errors for your AuthenticationProvider class when you’re in the WAS console.  Actually – I found these only when I was trying to change the ISIMSecurityDomain properties.
  • Finally, you need to add your new jar to the ITIM_LIB shared library.  Now, this isn’t that obvious at first, but it would appear that there are multiple classloaders working in ISIM so what I found is that login/authentication works fine, web services work fine, but JNDI calls from TDI don’t.  The solution is to add the class to ITIM_LIB.  The error I had was;
  • com.myorg.adauthentication.ADProviderFactory incompatible with com.ibm.itim.authentication.AuthenticationProviderFactory ( class java.lang.ClassCastException)

Now that’s a little unpleasant, and it directs you back to your AuthenticationProviderFactory.  This problem is actually a classloader problem.  Because the classloader that is the login page loads the class and then the classloader that is the JNDI event handler also loads the class, they consider the classes to be different and then throw this exception.  So, by putting the jar into the ITIM_LIB shared library, you’re allowing the parent classloader to load the class – then when the child classloaders load it they can resolve the class to the common type that the parent loaded and this exception is avoided.  Ok – that was the longest explanation for putting something into ITIM_LIB ever…..

 

Now – with that in hand, restart the application servers (and the DMgr) if you’re in a cluster) and you should be ok.  I would  expect that you could use a symlink to the jar to avoid having multiple copies of the jar (not tested so don’t shoot me).

That’s it – you should now have your custom authentication provider working and authenticating your various clients – user’s logging in, web services, JNDI, etc…