Friday, May 30, 2008

Authenticating Struts2 Applications using Interceptor

When I needed to introduce authentication into my existing application, I tried searching for an Interceptor written and shared by someone on internet. And as I guessed, I found some really helpful pieces of code, ready-to-use.

As I closely observed them, I found that they were implemented in almost similar fashion. What was common in both of them was the fact that 'interceptor was authenticating the user on login attempt'. I somehow wasn't comfortable with the idea of putting business logic in Interceptor. I thought, when a user is trying to log on to the system, a Login action should be called to Log the user into the system. I believe the interceptor should only keep a watch on the requests rather than processing them. Let request-processing be done by Actions.

So I wrote my own AuthenticationInterceptor.

  • It doesn't authenticate the user by itself, but just allows the 'LoginAttempt Request' being submitted to 'Login Action'.
  • When an un-authenticated user is attempting to invoke any action, it redirects request to Login page.
  • It just 'observes' all requests from an authenticated user.

I believe the code is self explanatory. Let me know if anything is not clear.

/**
* @author Rushikesh Thakkar
*/

@SuppressWarnings({"serial", "unchecked"})
public class AuthenticationInterceptor extends AbstractInterceptor {

private Map request, session;
public String intercept (ActionInvocation invocation) throws Exception {

session = invocation.getInvocationContext().getSession();
request = invocation.getInvocationContext().getParameters();

User user = (User) session.get(Constants.USER_KEY);

// CHECK IF THE USER IS ATTEMPTING TO LOGIN
boolean loginAttempt = request.get(Constants.LOGIN_ATTEMPT) == null ? false : true;

// CHECK IF THE USER IS ATTEMPTING TO LOGOUT
boolean logoutAttempt = request.get(Constants.LOGOUT_ATTEMPT) == null ? false : true;

System.out.println("__loginAttempt: " + loginAttempt);
System.out.println("__logoutAttempt: " + logoutAttempt);

if (user != null) { // USER IS ALREADY LOGGED IN
nbsp;if (!loginAttempt && logoutAttempt) // USER IS TRYING TO LOGOUT
return invocation.invoke();
else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return invocation.invoke();

} else { // USER IS NOT LOGGED IN
System.out.println("#12");
if (loginAttempt) { // USER IS TRYING TO LOGIN
return invocation.invoke();
} else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return "show-login";
}
}
}


Disclaimer: The code may not be perfect. Please test is thoroughly before using, and let me know if any correction is needed.

No comments: