Ben,
Thank you for your response.

Originally Posted by
Ben Alex
Does the above help at all? If not, would you mind posting a more detailed description of your use case as well as your current isPasswordCorrect method so I can offer some more specific advice.
Yes, the above comments do help. It gives me a better understanding of the internals of Acegi's login and authentications process. The security requirements of the application are: to not allow a user to start a new HttpSession if one has already started for that user (this may not be the same as a Logical session); and to lock the account if the user has 5 or more failed login attempts. The second requirement I was able to implement by trapping failed login attempts in the AppListener (See, AppListener code below). The authenticationDao.updateUserFailedLoginAttempts method increments a count that is stored into the authentication repository. And in the CustomDaoAuthenticationProvider.isPasswordCorrect method I check the failedLoginAttempts count, if it exceeds 5 then set the return results to false (See, CustomDaoAuthenticationProvider code below).
Code:
public class AppListener implements ApplicationListener, InitializingBean,
ApplicationContextAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(AppListener.class);
private ApplicationContext context;
private CustomAuthenticationDao authenticationDao;
//~ Methods ================================================================
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
public void setAuthenticationDao(CustomAuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
public CustomAuthenticationDao getAuthenticationDao() {
return authenticationDao;
}
public ApplicationContext getContext() {
return context;
}
public void afterPropertiesSet() throws Exception {
if (this.authenticationDao == null) {
throw new IllegalArgumentException("An Authentication DAO must be set");
}
}
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof AuthenticationFailurePasswordEvent) {
AuthenticationFailurePasswordEvent authEvent = (AuthenticationFailurePasswordEvent) event;
authenticationDao.updateUserFailedLoginAttempts(authEvent.getUser());
if (logger.isWarnEnabled()) {
logger.warn(
"Authentication failed due to incorrect password for user: "
+ authEvent.getUser().getUsername() + "; details: "
+ authEvent.getAuthentication().getDetails());
}
}
if (event instanceof AuthenticationFailureUsernameOrPasswordEvent) {
AuthenticationFailureUsernameOrPasswordEvent authEvent = (AuthenticationFailureUsernameOrPasswordEvent) event;
authenticationDao.updateUserFailedLoginAttempts(authEvent.getUser());
if (logger.isWarnEnabled()) {
logger.warn(
"Authentication failed due to invalid username or password: "
+ authEvent.getUser().getUsername() + "; details: "
+ authEvent.getAuthentication().getDetails());
}
}
if (event instanceof AuthenticationSuccessEvent) {
AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;
authenticationDao.saveUserAuthDetails(authEvent.getUser(),
authEvent.getAuthentication().getDetails());
if (logger.isInfoEnabled()) {
logger.info("Authentication success for user: "
+ authEvent.getUser().getUsername() + "; details: "
+ authEvent.getAuthentication().getDetails());
}
}
}
}
Code:
public class CustomDaoAuthenticationProvider extends DaoAuthenticationProvider {
protected boolean isPasswordCorrect(Authentication authentication,
UserDetails user) {
boolean result = super.isPasswordCorrect(authentication, user);
Object details = authentication.getDetails();
if (result) {
if ((user instanceof MpUser) && (details instanceof AuthDetails)) {
AuthDetails authDetails = (AuthDetails) details;
MpUser mpUser = (MpUser) user;
String authSessionId = authDetails.getSessionId();
String userSessionId = mpUser.getLastSessionId();
if ((authSessionId != null) && (userSessionId != null)) {
if (!authSessionId.equals(userSessionId)) {
/*
* TODO need to put exception logic here maybe
*/
/*
* TODO Commeted out result because of issues.
* result = false;
*/
}
}
Long failedLoginAttempts = mpUser.getFailedAttemptsCount();
/*
* Limit users to only 5 failed login attempts
*/
if (failedLoginAttempts != null) {
if (failedLoginAttempts.longValue() >= 5) {
result = false;
}
}
}
}
return result;
}
}
Thank you again for any comments that you may provide.
Guy