From 3eb614987744e148e4e8554821e2b7e421cf1360 Mon Sep 17 00:00:00 2001 From: Ray Krueger Date: Thu, 9 Dec 2004 22:09:35 +0000 Subject: [PATCH] New LoginExceptionResolver interface and base implementation to handle LoginExceptions thrown in the Jaas API. I am commiting this now so that it isn't lost, while a PropertyEditor based solution is investigated. --- .../jaas/DefaultLoginExceptionResolver.java | 37 +++++++++++++++ .../jaas/JaasAuthenticationProvider.java | 31 +++++++++---- .../jaas/LoginExceptionResolver.java | 46 +++++++++++++++++++ 3 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java b/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java new file mode 100644 index 0000000000..970adecbfe --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java @@ -0,0 +1,37 @@ +/* Copyright 2004 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.AcegiSecurityException; +import net.sf.acegisecurity.AuthenticationServiceException; + +import javax.security.auth.login.LoginException; + + +/** + * This LoginExceptionResolver simply wraps the LoginException with an + * AuthenticationServiceException. + * + * @author $author$ + * @version $Revision$ + */ +public class DefaultLoginExceptionResolver implements LoginExceptionResolver { + //~ Methods ================================================================ + + public AcegiSecurityException resolveException(LoginException e) { + return new AuthenticationServiceException(e.getMessage(), e); + } +} diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java index eef38d71f2..878c4b581b 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java @@ -15,9 +15,9 @@ package net.sf.acegisecurity.providers.jaas; +import net.sf.acegisecurity.AcegiSecurityException; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationException; -import net.sf.acegisecurity.AuthenticationServiceException; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.providers.AuthenticationProvider; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -159,6 +159,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, //~ Instance fields ======================================================== private ApplicationContext context; + private LoginExceptionResolver loginExceptionResolver = new DefaultLoginExceptionResolver(); private Resource loginConfig; private String loginContextName = "ACEGI"; private AuthorityGranter[] authorityGranters; @@ -184,9 +185,11 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, } /** - * DOCUMENT ME! + * Returns the AuthorityGrannter array that was passed to the {@link + * #setAuthorityGranters(AuthorityGranter[])} method, or null if it none + * were ever set. * - * @return The AuthorityGranter array + * @return The AuthorityGranter array, or null * * @see #setAuthorityGranters(net.sf.acegisecurity.providers.jaas.AuthorityGranter[]) */ @@ -249,6 +252,15 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, return loginContextName; } + public void setLoginExceptionResolver( + LoginExceptionResolver loginExceptionResolver) { + this.loginExceptionResolver = loginExceptionResolver; + } + + public LoginExceptionResolver getLoginExceptionResolver() { + return loginExceptionResolver; + } + public void afterPropertiesSet() throws Exception { if (loginConfig == null) { throw new ApplicationContextException("loginConfig must be set on " @@ -284,7 +296,6 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, * AuthenticationServiceException, with the message of the * LoginException that will be thrown, should the * loginContext.login() method fail. - * @throws AuthenticationServiceException DOCUMENT ME! */ public Authentication authenticate(Authentication auth) throws AuthenticationException { @@ -334,12 +345,12 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, //we're done, return the token. return token; - } catch (LoginException e) { - context.publishEvent(new JaasAuthenticationFailedEvent(auth, e)); + } catch (LoginException loginException) { + AcegiSecurityException ase = loginExceptionResolver + .resolveException(loginException); - //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()); + context.publishEvent(new JaasAuthenticationFailedEvent(auth, ase)); + throw ase; } } @@ -366,10 +377,12 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbackHandlers.length; i++) { JaasAuthenticationCallbackHandler handler = callbackHandlers[i]; + handler.setAuthentication(authentication); for (int j = 0; j < callbacks.length; j++) { Callback callback = callbacks[j]; + handler.handle(callback); } } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java b/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java new file mode 100644 index 0000000000..c4a8098945 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java @@ -0,0 +1,46 @@ +/* Copyright 2004 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.AcegiSecurityException; + +import javax.security.auth.login.LoginException; + + +/** + * The JaasAuthenticationProvider takes an instance of LoginExceptionResolver + * to resolve LoginModule specific exceptions to Acegi exceptions. For + * instance, a configured login module could throw a + * ScrewedUpPasswordException that extends LoginException, in this instance + * the LoginExceptionResolver implementation would return a {@link + * net.sf.acegisecurity.BadCredentialsException}. + * + * @author $author$ + * @version $Revision$ + */ +public interface LoginExceptionResolver { + //~ Methods ================================================================ + + /** + * Translates a Jaas LoginException to an AcegiSecurityException. + * + * @param e The LoginException thrown by the configured LoginModule. + * + * @return The AcegiSecurityException that the JaasAuthenticationProvider + * should throw. + */ + public AcegiSecurityException resolveException(LoginException e); +}