Hello,

First, my apologies if this is rather long-winded.

I want to use Acegi for a new project I am currently in the initial design phase of. We have a requirement that users be authenticated by username, password, and zipcode. The user info will be coming out of a legacy database.

My initial thoughts for fulfilling these requirements were:

1.) subclass net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken
to add the zip code field

2.) subclass net.sf.acegisecurity.providers.dao.User, again to add the zip code field.

3.) implement net.sf.acegisecurity.providers.dao.AuthenticationDao to pull my User subclass and the GrantedAuthority list from the legacy database.

This does leave me with a two open issues:

1.) populating the zip code field in the servlet filter - the obvious solution is to create my own filter with almost exact logic as net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter

2.) validating the include zip code matches the zip code in the database. This requires creating a subclass of net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider. However, I don't find a nice way to hook into its logic, and reimplementing the authenticate method from scratch doesn't seem like good design to me. Also, isPasswordCorrect is private, so I can override it and finally the argument to AuthenticationDao is a single String so I can't validate the zip code in the dao (which I considered for awhile) without sending the zipcode and username together in that String somehow.

So I was wondering if you'd be interested in adding a method to DaoAuthenticationProvider that subclasses could override to validate custom attributes of custom User implementations.

For example, from DaoAuthenticationProvider's authenticate method:

<snip>

if (!isPasswordCorrect(authentication, user)) {
    // Password incorrect, so ensure we're using most current password
    if (cacheWasUsed) {
        cacheWasUsed = false;
        user = getUserFromBackend(authentication);
    }

    if (!isPasswordCorrect(authentication, user)) {
        if (this.ctx != null) {
            ctx.publishEvent(
                new AuthenticationFailurePasswordEvent(authentication, user));
        }

        throw new BadCredentialsException("Bad credentials presented");
    }
}

/*

Here I'd like add a call before the next section of code caches the user and publishes the event such as:

if (isAuthenticationCorrect(authentication, user)) {

...

}

*/

if (!cacheWasUsed) {
    // Put into cache
    this.userCache.putUserInCache(user);

    // As this appears to be an initial login, publish the event
    if (this.ctx != null) {
        ctx.publishEvent(new AuthenticationSuccessEvent(
            authentication, user));
    }
}
<snip/>

Actually, the default implementation of isAuthenticationCorrect(authentication, user) could be the code found in the current isPasswordCorrect method.

For the filter, I think it might make more sense it just create a new one rather than adding a hook for subclasses to instantiate their custom Authenticate implementations.

What do you think?

thanks in advance,

Scott


Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.

Reply via email to