JAAS, Securing J2EE Applications: Securing Web Components - Implementing the JAAS Security Module
(Page 4 of 7 )
So much for theories. Now, it's time to have a look at the steps involved in implementing JAAS as a module. The implementation I am discussing below has been developed to provide security for a Java Mail application (experimental) that I am currently trying out for my personal use. To write a custom implementation, use the following steps:
- Implement the LoginModule.
- Write the CallBackHandler.
- Providing custom implementations for Principal and Action (this is optional).
- Configure the JAAS policy file.
- Configure the J2EE Application server.
Before going into the details of the implementation, the package you need to import for all the steps is:
javax.security.
1. Implement the LoginModule
LoginModule is one of the core modules of JAAS. It encapsulates the authentication logic intended for the JAAS framework. To implement LoginModule, one must override the following four methods:
a. login():
This method performs the tasks of fetching the login information and authenticating the user. In short the logic to authenticate a user comes here. Fetching the login information is done as shone below:
Callback[] callbacks=new Callbacks[2];
Callbacks[0]=new NameCallback(“userModule username:”);
Callbacks[0]=new NameCallback(“userModule password:”,false);
callbackHandler.handle(calls);
It is obvious from the above code that login information is fetched using the CallBackHandler. Once the login information is gathered, the login method attempts to connect to the server. If connected, the method returns true. The following snippet shows the procedure.
boolean succeeded=false;
try{
user=((NameCallback)callbacks[0]).getName();
passwd=((NameCallback)callbacks[0]).getPassword();
props.put(Context.SECURITY_PRINCIPAL,user);
props.put(Context.SECURITY_CREDENTIALS,passwd);
ctx = new InitialDirContext(props);
succeeded =true;
}…
return succeeded;
In the try-catch block, it tries to connect to the LDAP server with the gathered information. If the connection succeeds (that is, InitialDirContext() doesn’t throw exceptions), the verification variable is set to true. Here instead of the LDAP server, the database server could also be used as the authenticating server.
- commit():
This method sets the validated username in the session context. The code to populate the subject with the roles and credentials (such as private keys) if any, also goes here. The code is as follows:
if(!succeeded)
return false;
else
{
userPrincipal=new userPrincipal(user);
if(!subject.getPrincipals().contains(userPrincipal)
subject.getPrincipals().add(userPrincipal);
…...……
commitSucceeded=true;
return true;
}
c. abort():
This method is called if the LoginContext’s overall authentication fails. This method is also triggered by the runtime if a runtime exception is generated. To do custom processing in case of authentication failure, the code would be as follows:
if(!succeed)//this is for authentication failure
{
return false;
}
else if(succeeded&&commitSucceeded==false)//this is for //runtime //error
{
user=null;
passwd=null;
throw new FailedLoginException(“Exception in Processin”);
}
d. logout():
Whenever user logs out, this method is called. So if you want to unset some credentials or release the resources held by the user, you can do it here. The code that I used is as follows:
subject.getPrincipals.remove(userPrincipal);
succeeded=false;
succeeded=commitSucceeded;
user=null;
if(password!=null)
password=null;
userPrincipal=null;
return true;
The class embedding the above code is:
public class MyLoginModule implements LoginModule
{
}
Next: 2. Write the CallBackHandler >>
More Java Articles
More By A.P.Rajshekhar