Skip to content

JAAS and Failover mechanism

October 12, 2009
tags:

Assuming that I have two login modules defined. And I need that if the first login module’s server is down then the second login module’s authentication process is executed. For this the following would be the configuration:


SampleLogin {
com.auth.CASLoginModule requisite;
com.auth.JNDILoginModule requisite;
};

Now requisite flag means that :
requisite – the LoginModule must succeed: it must return true from the login()
method. Unlike required LoginModules, the failure of a requisite LoginModule prevents the login() method of the remaining LoginModules from being called. However in case of success the remaining stack of login modules will be called.

The only thing that took me some time to understand was – what is the difference between returning false and throwing LoginException in JAAS. The difference is that “false” implies ignore this module and LoginException implies an authentication failure. Quote from the JAAS book by Cote:

To authenticate, the login() method first saves the username entered as a private field for later use to create Principals and credentials, and then returns true. Otherwise, a sub-class of LoginException,
javax.security.auth.login.FailedLoginException, is thrown. Returning false from the login() method signals to JAAS to ignore this LoginModule. You may want the LoginModule ignored if it has nothing to contribute to the Subject

So if our CAS authentication Server is down – return false. Otherwise return LoginException for authentication failure.

Other flags in JAAS:

required: other login modules called irrespective of the status of the current login module.

sufficient: if A succeeds, B is not called, but if A authentication fails(i.e LoginException) then B is called.

optional: It is optional, success or failure does not matter. Authentication passes down the stack.

UPDATE

The below matrix explains the stacking clearly. The required flag  determines the result of aggregate authentication result.

Login2 Authentication Status

SampleLoginModule required pass pass pass pass fail fail fail fail
NTLoginModule sufficient pass fail fail fail pass fail fail fail
SmartCard requisite * pass pass fail * pass pass fail
Kerberos optional * pass fail * * pass fail *
Overall Authentication pass pass pass fail fail fail fail fail

* = trivial value due to control returning to the application because a previous requisite module failed or a previous sufficient module succeeded.

We cannot use required or optional flag because in both cases the next login module is always executed irrespective of the status of the current login module.  Requires mandates authentication where as optional makes authentication optional. So we are left with two flags : requisite and sufficient. Sufficient does not make authentication mandatory – and so this flag cannot be used. Thus we need to use the requisite flag. The requisite flag makes authentication mandatory and calls the next login module if authentication succeeds and returns to application immediately if authentication fails. Ideally for failover we would have liked to create our own custom control flag that only calls the next login module if the current login module throws a specific exception or sets a specific value.

Since that is not available, (I did not see any example of custom control flag) and it is expensive to call the second login module every time when user is authenticated successfully – what we can do instead of stacking is to do nesting of modules.

Now in Jboss if you are extending the UsernamePasswordLoginModule then the behavior or exception or flag as discussed above is no longer valid. Firstly the three methods that you would need to override are:

protected Group[] getRoleSets() throws LoginException
protected boolean validatePassword(String password, String expectedPassword)
protected String getUsersPassword()

And in the validatePassword you cannot throw LoginException ! 🙂 Instead you can catch “any” exception and call method setValidateError(e);  Now that also makes the task of stacking for fail over tricky unless one directly extends AbstractLoginModule in jboss and studies its implementation . (Need to study this – would post an update on this later…)

<application-policy name="JBossWS">
<authentication>
<login-module code="com.jboss.CASLoginModule" flag="requisite">
<module-option name="FailOverLoginModule"> com.jboss.JNDILoginModule </module-option>
</login-module>
  </authentication>
</application-policy>

The overall authentication succeeds only if all Required and Requisite LoginModules succeed. If a Sufficient LoginModule is configured and succeeds, then only the Required and Requisite LoginModules prior to that Sufficient LoginModule need to have succeeded for the overall authentication to succeed. If no Required or Requisite LoginModules are configured for an application, then at least one Sufficient or Optional LoginModule must succeed.

Advertisements
2 Comments leave one →
  1. nohros permalink
    May 3, 2012 9:30 pm

    Why not use Sufficient? It is not mandatory, but if it succeeds, control immediately returns to the caller and if it fails, authentication continues down the login module list. This is how a failover mechanism shold work, right?

  2. techzen permalink*
    May 5, 2012 2:46 pm

    How do you differentiate between the failure caused by authentication failure or the server not being available – in the case of sufficient?.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: