PDA

View Full Version : RFE: Provide a way to translate the JAAS LoginExceptions



sds
Oct 14th, 2004, 10:21 AM
In my JAASLoginModule, I throw a subclass of LoginException upon InvalidCredentials, UserNotFound, .... However, the current LDAPProvider does not foresee a way to resolve the LoginException into an Acegi exception. I could just throw an Acegi exception straight away, but that would mean that the JAAS login module is dependent on Acegi, while it is the other way around.

To make a long story short, could the class JaasAuthenticationProvider be alter to call a method for resolving the LoginException, so I can subclass it and provide my own resolver ?



public Authentication authenticate(Authentication auth)
try {
....
} catch (LoginException e) {
context.publishEvent(new JaasAuthenticationFailedEvent(auth, e));

// This could become the implementation of resolveLoginException(e); so I can subclass and change behavior
//We have no way of knowing what caused the exception, so we cannot throw BadCredentialsException, DisabledException, or LockedException.
//So we'll just throw an AuthenticationServiceException
throw new AuthenticationServiceException(e.toString());
}


Stefaan

sds
Oct 15th, 2004, 02:02 AM
What's more, if the LoginModule throws an Acegi exception straight away, it gets wrapped in a LoginException by JAAS. The exception handler could look if the target exception of the LoginException is an Acegi exception, and use that one.



public Authentication authenticate(Authentication auth)
try {
....
} catch (LoginException e) {
context.publishEvent(new JaasAuthenticationFailedEvent(auth, e));
resolveLoginException(e);
}
...

/**
* Tries to resolves a JAAS login exception into an Acegie exception, such as BadCredentialsException, DisabledException, UsernameNotFoundException or LockedException
* @param loginException The login exception causing the failed login
* @return AcegiSecurityException The corresponding exception of Acegi
*/
public AcegiSecurityException resolveLoginException(LoginException loginException) {
// if the code needs to be compatible with pre 1.4, we need to use reflection here
if (loginException.getCause() instanceof AcegiSecurityException) {
return (AcegiSecurityException)loginException.getCause ();
} else {
//We have no way of knowing what caused the exception, so we return the general AuthenticationServiceException
//So we'll just throw an AuthenticationServiceException
throw new AuthenticationServiceException(loginException.toSt ring());
}
}


Ben, if u want, I'll be happy to contribute the modified JaasAuthenticationProvider (and test case).

Stefaan.

RayKrueger
Oct 15th, 2004, 02:47 PM
I like both ideas actually...

How about I implement the translateException method, with the default functionality being to check the getCause() method for an AcegiSecurityException.

For example....




public Authentication authenticate(Authentication auth) {
try {
...
} catch (LoginException e) {
AcegiSecurityException translatedException = translateException(e);
context.publishEvent(new JaasAuthenticationFailedEvent(auth, translatedException));
throw translatedException;
}
}

return null;
}

protected AcegiSecurityException translateException(LoginException e) {
if (e.getCause() instanceof AcegiSecurityException) {
return (AcegiSecurityException) e.getCause();
} else {
return new AuthenticationServiceException(e.toString());
}
}