diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java
index 1b2dfa99cc..df344c6c8b 100644
--- a/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java
+++ b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java
@@ -1,25 +1,51 @@
+/* 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 java.security.Principal;
+
/**
- * The AuthorityGranter interface is used to map a given principal to a role name.
- * If a Windows NT login module were to be used from JAAS, an AuthrityGranter implementation could be created
- * to map a NT Group Principal to a ROLE_USER role for instance.
- *
+ * The AuthorityGranter interface is used to map a given principal to a role
+ * name.
+ *
+ *
+ * If a Windows NT login module were to be used from JAAS, an AuthrityGranter
+ * implementation could be created to map a NT Group Principal to a ROLE_USER
+ * role for instance.
+ *
+ * Before a JaasAuthenticationCallbackHandler is asked to 'handle' any + * callbacks, it is first passed the Authentication object that the login + * attempt is for. NOTE: The Authentication object has not been + * 'authenticated' yet. *
- *
* This AuthenticationProvider
is capable of validating {@link
- * net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken} requests contain the correct username and password.
+ * net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken}
+ * requests contain the correct username and password.
*
+ * This implementation is backed by a JAAS + * configuration. The loginConfig property must be set to a given JAAS + * configuration file. This setter accepts a Spring {@link + * org.springframework.core.io.Resource} instance. It should point to a JAAS + * configuration file containing an index matching the {@link + * #setLoginContextName(java.lang.String) loginContextName} property. + *
+ * + *+ * For example: If this JaasAuthenticationProvider were configured in a Spring + * WebApplicationContext the xml to set the loginConfiguration could be as + * follows... *
* <property name="loginConfig"> * <value>/WEB-INF/login.conf</value> * </property> ** - * - * - * The loginContextName should coincide with a given index in the loginConfig specifed. - * The loginConfig file used in the JUnit tests appears as the following... + * + *
+ * The loginContextName should coincide with a given index in the loginConfig + * specifed. The loginConfig file used in the JUnit tests appears as the + * following... *
* JAASTest { * net.sf.acegisecurity.providers.jaas.TestLoginModule required; * }; *- * Using the example login configuration above, the loginContextName property would be set as JAASTest... + * Using the example login configuration above, the loginContextName property + * would be set as JAASTest... *
* <property name="loginContextName"> * <value>JAASTest</value> * </property> ** - * - * - * When using JAAS login modules as the authentication source, sometimes the - * LoginContext - * will require CallbackHandlers. - * The JaasAuthenticationProvider uses an internal CallbackHandler to - * wrap the {@link JaasAuthenticationCallbackHandler}s configured in the ApplicationContext. When the LoginContext calls - * the internal CallbackHandler, control is passed to each {@link JaasAuthenticationCallbackHandler} for each Callback passed. + * + *
+ * When using JAAS login modules as the authentication source, sometimes the LoginContext + * will require CallbackHandlers. The JaasAuthenticationProvider uses + * an internal CallbackHandler + * to wrap the {@link JaasAuthenticationCallbackHandler}s configured in the + * ApplicationContext. When the LoginContext calls the internal + * CallbackHandler, control is passed to each {@link + * JaasAuthenticationCallbackHandler} for each Callback passed. *
- * - * {@link JaasAuthenticationCallbackHandler}s are passed to the JaasAuthenticationProvider through the - * {@link #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) callbackHandlers} property. - *+ * + *+{ * {@link JaasAuthenticationCallbackHandler}s are passed to the + * JaasAuthenticationProvider through the {@link + * #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) + * callbackHandlers} property. +} *
* <property name="callbackHandlers"> * <list> * <bean class="net.sf.acegisecurity.providers.jaas.TestCallbackHandler"/> @@ -87,13 +126,20 @@ import java.util.Set; * </property> ** - * - * - * After calling LoginContext.login(), the JaasAuthenticationProvider will retrieve the returned Principals from the Subject (LoginContext.getSubject().getPrincipals). - * Each returned principal is then passed to the configured {@link AuthorityGranter}s. An AuthorityGranter is a mapping between a returned Principal, and a role name. - * If an AuthorityGranter wishes to grant an Authorization a role, it returns that role name from it's {@link AuthorityGranter#grant(java.security.Principal)} method. - * The returned role will be applied to the Authorization object as a {@link GrantedAuthority}. - * + * + *+ * After calling LoginContext.login(), the JaasAuthenticationProvider will + * retrieve the returned Principals from the Subject + * (LoginContext.getSubject().getPrincipals). Each returned principal is then + * passed to the configured {@link AuthorityGranter}s. An AuthorityGranter is + * a mapping between a returned Principal, and a role name. If an + * AuthorityGranter wishes to grant an Authorization a role, it returns that + * role name from it's {@link AuthorityGranter#grant(java.security.Principal)} + * method. The returned role will be applied to the Authorization object as a + * {@link GrantedAuthority}. + *
+ * + ** AuthorityGranters are configured in spring xml as follows... *
* <property name="authorityGranters"> @@ -108,36 +154,151 @@ import java.util.Set; * @author Ray Krueger * @version $Id$ */ -public class JaasAuthenticationProvider implements AuthenticationProvider, InitializingBean, ApplicationContextAware { +public class JaasAuthenticationProvider implements AuthenticationProvider, + InitializingBean, ApplicationContextAware { + //~ Instance fields ======================================================== private ApplicationContext context; - private String loginContextName = "ACEGI"; private Resource loginConfig; - private JaasAuthenticationCallbackHandler[] callbackHandlers; + private String loginContextName = "ACEGI"; private AuthorityGranter[] authorityGranters; + private JaasAuthenticationCallbackHandler[] callbackHandlers; + + //~ Methods ================================================================ + + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.context = applicationContext; + } /** - * Attempts to login the user given the Authentication objects principal and credential + * Set the AuthorityGranters that should be consulted for role names to be + * granted to the Authentication. + * + * @param authorityGranters AuthorityGranter array + * + * @see JaasAuthenticationProvider + */ + public void setAuthorityGranters(AuthorityGranter[] authorityGranters) { + this.authorityGranters = authorityGranters; + } + + /** + * DOCUMENT ME! + * + * @return The AuthorityGranter array + * + * @see #setAuthorityGranters(net.sf.acegisecurity.providers.jaas.AuthorityGranter[]) + */ + public AuthorityGranter[] getAuthorityGranters() { + return authorityGranters; + } + + /** + * Set the JAASAuthentcationCallbackHandler array to handle callback + * objects generated by the LoginContext.login method. + * + * @param callbackHandlers Array of JAASAuthenticationCallbackHandlers + */ + public void setCallbackHandlers( + JaasAuthenticationCallbackHandler[] callbackHandlers) { + this.callbackHandlers = callbackHandlers; + } + + /** + * DOCUMENT ME! + * + * @return the JAASAuthenticationCallbackHandlers. + * + * @see #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) + */ + public JaasAuthenticationCallbackHandler[] getCallbackHandlers() { + return callbackHandlers; + } + + /** + * Set the JAAS login configuration file. + * + * @param loginConfig Spring + * Resource + * + * @see JAAS + * Reference + */ + public void setLoginConfig(Resource loginConfig) { + this.loginConfig = loginConfig; + } + + public Resource getLoginConfig() { + return loginConfig; + } + + /** + * Set the loginContextName, this name is used as the index to the + * configuration specified in the loginConfig property. + * + * @param loginContextName + */ + public void setLoginContextName(String loginContextName) { + this.loginContextName = loginContextName; + } + + public String getLoginContextName() { + return loginContextName; + } + + public void afterPropertiesSet() throws Exception { + if (loginConfig == null) { + throw new ApplicationContextException("loginConfig must be set on " + + getClass()); + } + + if (loginContextName == null) { + throw new ApplicationContextException( + "loginContextName must be set on " + getClass()); + } + + int n = 1; + + while (Security.getProperty("login.config.url." + n) != null) { + n++; + } + + Security.setProperty("login.config.url." + n, + loginConfig.getURL().toString()); + } + + /** + * Attempts to login the user given the Authentication objects principal + * and credential * * @param auth The Authentication object to be authenticated. - * @return The authenticated Authentication object, with it's grantedAuthorities set. - * @throws AuthenticationException This implementation does not handle 'locked' or 'disabled' accounts. - * This method only throws a AuthenticationServiceException, with the message of the LoginException that will be thrown, - * should the loginContext.login() method fail. + * + * @return The authenticated Authentication object, with it's + * grantedAuthorities set. + * + * @throws AuthenticationException This implementation does not handle + * 'locked' or 'disabled' accounts. This method only throws a + * 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 { + public Authentication authenticate(Authentication auth) + throws AuthenticationException { if (auth instanceof UsernamePasswordAuthenticationToken) { UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth; try { - //Create the LoginContext object, and pass our InternallCallbackHandler - LoginContext lc = new LoginContext(loginContextName, new InternalCallbackHandler(auth)); + LoginContext lc = new LoginContext(loginContextName, + new InternalCallbackHandler(auth)); //Attempt to login the user, the LoginContext will call our InternalCallbackHandler at this point. lc.login(); - //create a set to hold the authorities, and add any that have already been applied. Set authorities = new HashSet(); @@ -147,34 +308,41 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Initi //get the subject principals and pass them to each of the AuthorityGranters Set principals = lc.getSubject().getPrincipals(); - for (Iterator iterator = principals.iterator(); iterator.hasNext();) { + + for (Iterator iterator = principals.iterator(); + iterator.hasNext();) { Principal principal = (Principal) iterator.next(); + for (int i = 0; i < authorityGranters.length; i++) { AuthorityGranter granter = authorityGranters[i]; String role = granter.grant(principal); + //If the granter doesn't wish to grant any authority, it should return null. if (role != null) { - authorities.add(new JaasGrantedAuthority(role, principal)); + authorities.add(new JaasGrantedAuthority(role, + principal)); } } } //Convert the authorities set back to an array and apply it to the token. - token.setAuthorities((GrantedAuthority[]) authorities.toArray(new GrantedAuthority[authorities.size()])); + token.setAuthorities((GrantedAuthority[]) authorities.toArray( + new GrantedAuthority[authorities.size()])); //Publish the success event context.publishEvent(new JaasAuthenticationSuccessEvent(token)); //we're done, return the token. return token; - } catch (LoginException e) { context.publishEvent(new JaasAuthenticationFailedEvent(auth, e)); + //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()); } } + return null; } @@ -182,104 +350,24 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Initi return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass); } - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.context = applicationContext; - } - - public String getLoginContextName() { - return loginContextName; - } - - /** - * Set the loginContextName, this name is used as the index to the configuration specified in the loginConfig property. - * - * @param loginContextName - */ - public void setLoginContextName(String loginContextName) { - this.loginContextName = loginContextName; - } - - public Resource getLoginConfig() { - return loginConfig; - } - - /** - * Set the JAAS login configuration file. - * - * @param loginConfig Spring Resource - * @see JAAS Reference - */ - public void setLoginConfig(Resource loginConfig) { - this.loginConfig = loginConfig; - } - - public void afterPropertiesSet() throws Exception { - - if (loginConfig == null) - throw new ApplicationContextException("loginConfig must be set on " + getClass()); - - if (loginContextName == null) - throw new ApplicationContextException("loginContextName must be set on " + getClass()); - - int n = 1; - while (Security.getProperty("login.config.url." + n) != null) n++; - - Security.setProperty("login.config.url." + n, loginConfig.getURL().toString()); - } - - /** - * @return the JAASAuthenticationCallbackHandlers. - * @see #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) - */ - public JaasAuthenticationCallbackHandler[] getCallbackHandlers() { - return callbackHandlers; - } - - /** - * Set the JAASAuthentcationCallbackHandler array to handle callback objects generated by the - * LoginContext.login method. - * - * @param callbackHandlers Array of JAASAuthenticationCallbackHandlers - */ - public void setCallbackHandlers(JaasAuthenticationCallbackHandler[] callbackHandlers) { - this.callbackHandlers = callbackHandlers; - } - - /** - * @return The AuthorityGranter array - * @see #setAuthorityGranters(net.sf.acegisecurity.providers.jaas.AuthorityGranter[]) - */ - public AuthorityGranter[] getAuthorityGranters() { - return authorityGranters; - } - - /** - * Set the AuthorityGranters that should be consulted for role names to be granted to the Authentication. - * - * @param authorityGranters AuthorityGranter array - * @see JaasAuthenticationProvider - */ - public void setAuthorityGranters(AuthorityGranter[] authorityGranters) { - this.authorityGranters = authorityGranters; - } - + //~ Inner Classes ========================================================== /** * Wrapper class for JAASAuthenticationCallbackHandlers */ private class InternalCallbackHandler implements CallbackHandler { - private Authentication authentication; public InternalCallbackHandler(Authentication authentication) { this.authentication = authentication; } - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - + public void handle(Callback[] callbacks) + 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/JaasGrantedAuthority.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java index fb9727fb21..01c28199db 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java @@ -1,26 +1,48 @@ +/* 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.GrantedAuthorityImpl; import java.security.Principal; + /** - * Extends GrantedAuthorityImpl to hold the principal that an AuthorityGranter justified as a reason to grant this Authority. - *
+ * Extends GrantedAuthorityImpl to hold the principal that an AuthorityGranter + * justified as a reason to grant this Authority.
* * @author Ray Krueger * @version $Id$ + * * @see AuthorityGranter */ public class JaasGrantedAuthority extends GrantedAuthorityImpl { + //~ Instance fields ======================================================== private Principal principal; + //~ Constructors =========================================================== + public JaasGrantedAuthority(String role, Principal principal) { super(role); this.principal = principal; } + //~ Methods ================================================================ + public Principal getPrincipal() { return principal; } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java index 0494a8048d..d874494055 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java @@ -1,40 +1,70 @@ +/* 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.Authentication; +import java.io.IOException; + import javax.security.auth.callback.Callback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.UnsupportedCallbackException; -import java.io.IOException; + /** - * The most basic Callbacks to be handled when using a LoginContext from JAAS, are the NameCallback and PasswordCallback. - * The acegi security framework provides the JaasNameCallbackHandler specifically tailored to handling the NameCallback. - *
+ * The most basic Callbacks to be handled when using a LoginContext from JAAS, + * are the NameCallback and PasswordCallback. The acegi security framework + * provides the JaasNameCallbackHandler specifically tailored to handling the + * NameCallback.
* * @author Ray Krueger * @version $Id$ - * @see Callback - * @see NameCallback + * + * @see Callback + * @see NameCallback */ -public class JaasNameCallbackHandler implements JaasAuthenticationCallbackHandler { +public class JaasNameCallbackHandler + implements JaasAuthenticationCallbackHandler { + //~ Instance fields ======================================================== private Authentication authentication; + //~ Methods ================================================================ + public void setAuthentication(Authentication authentication) { this.authentication = authentication; } /** - * If the callback passed to the 'handle' method is an instance of NameCallback, the JaasNameCallbackHandler will call, - * callback.setName(authentication.getPrincipal().toString()). Where 'authentication' is the {@link Authentication} - * object used in the {@link #setAuthentication(net.sf.acegisecurity.Authentication) setAuthentication} method. + * If the callback passed to the 'handle' method is an instance of + * NameCallback, the JaasNameCallbackHandler will call, + * callback.setName(authentication.getPrincipal().toString()). Where + * 'authentication' is the {@link Authentication} object used in the + * {@link #setAuthentication(net.sf.acegisecurity.Authentication) + * setAuthentication} method. * * @param callback + * * @throws IOException * @throws UnsupportedCallbackException */ - public void handle(Callback callback) throws IOException, UnsupportedCallbackException { + public void handle(Callback callback) + throws IOException, UnsupportedCallbackException { if (callback instanceof NameCallback) { NameCallback ncb = (NameCallback) callback; ncb.setName(authentication.getPrincipal().toString()); diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java index 2f1da331b9..82813d8346 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java @@ -1,40 +1,71 @@ +/* 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.Authentication; +import java.io.IOException; + import javax.security.auth.callback.Callback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; -import java.io.IOException; + /** - * The most basic Callbacks to be handled when using a LoginContext from JAAS, are the NameCallback and PasswordCallback. - * The acegi security framework provides the JaasPasswordCallbackHandler specifically tailored to handling the PasswordCallback. - *
+ * The most basic Callbacks to be handled when using a LoginContext from JAAS, + * are the NameCallback and PasswordCallback. The acegi security framework + * provides the JaasPasswordCallbackHandler specifically tailored to handling + * the PasswordCallback.
* * @author Ray Krueger * @version $Id$ - * @see Callback - * @see PasswordCallback + * + * @see Callback + * @see PasswordCallback */ -public class JaasPasswordCallbackHandler implements JaasAuthenticationCallbackHandler { +public class JaasPasswordCallbackHandler + implements JaasAuthenticationCallbackHandler { + //~ Instance fields ======================================================== private Authentication auth; + //~ Methods ================================================================ + public void setAuthentication(Authentication auth) { this.auth = auth; } /** - * If the callback passed to the 'handle' method is an instance of PasswordCallback, the JaasPasswordCallbackHandler will call, - * callback.setPassword(authentication.getCredentials().toString()). Where 'authentication' is the {@link Authentication} - * object used in the {@link JaasAuthenticationCallbackHandler#setAuthentication(net.sf.acegisecurity.Authentication) setAuthentication} method. + * If the callback passed to the 'handle' method is an instance of + * PasswordCallback, the JaasPasswordCallbackHandler will call, + * callback.setPassword(authentication.getCredentials().toString()). Where + * 'authentication' is the {@link Authentication} object used in the + * {@link + * JaasAuthenticationCallbackHandler#setAuthentication(net.sf.acegisecurity.Authentication) + * setAuthentication} method. * * @param callback + * * @throws IOException * @throws UnsupportedCallbackException */ - public void handle(Callback callback) throws IOException, UnsupportedCallbackException { + public void handle(Callback callback) + throws IOException, UnsupportedCallbackException { if (callback instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) callback; pc.setPassword(auth.getCredentials().toString().toCharArray()); diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java index 12e73383e7..81d9444ad5 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java @@ -1,25 +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.event; import net.sf.acegisecurity.Authentication; + /** - * Fired when LoginContext.login throws a LoginException, or if any other exception is thrown during that time. - *
+ * Fired when LoginContext.login throws a LoginException, or if any other + * exception is thrown during that time. * * @author Ray Krueger * @version $Id$ */ public class JaasAuthenticationFailedEvent extends JaasAuthenticationEvent { + //~ Instance fields ======================================================== private Exception exception; - public JaasAuthenticationFailedEvent(Authentication auth, Exception exception) { + //~ Constructors =========================================================== + + public JaasAuthenticationFailedEvent(Authentication auth, + Exception exception) { super(auth); this.exception = exception; } + //~ Methods ================================================================ + public Exception getException() { return exception; } - } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java index 5d13c43329..74f835f888 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java @@ -1,19 +1,36 @@ +/* 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.event; import net.sf.acegisecurity.Authentication; + /** - * Fired by the {@link net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider JaasAuthenticationProvider} after - * successfully logging the user into the LoginContext, handling all callbacks, and calling all AuthorityGranters. - *
+ * Fired by the {@link + * net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider + * JaasAuthenticationProvider} after successfully logging the user into the + * LoginContext, handling all callbacks, and calling all AuthorityGranters. * * @author Ray Krueger * @version $Id$ */ public class JaasAuthenticationSuccessEvent extends JaasAuthenticationEvent { + //~ Constructors =========================================================== public JaasAuthenticationSuccessEvent(Authentication auth) { super(auth); } - } diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java index ad87510621..6265a693d2 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java @@ -1,50 +1,87 @@ +/* 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 junit.framework.TestCase; + import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationException; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.Arrays; import java.util.List; + /** - * Insert comments here... - *
+ * DOCUMENT ME! * * @author Ray Krueger * @version $Id$ */ public class JaasAuthenticationProviderTests extends TestCase { + //~ Instance fields ======================================================== - private JaasAuthenticationProvider jaasProvider; private ApplicationContext context; + private JaasAuthenticationProvider jaasProvider; private JaasEventCheck eventCheck; - protected void setUp() throws Exception { - String resName = "/" + getClass().getName().replace('.', '/') + ".xml"; - context = new ClassPathXmlApplicationContext(resName); - eventCheck = (JaasEventCheck) context.getBean("eventCheck"); - jaasProvider = (JaasAuthenticationProvider) context.getBean("jaasAuthenticationProvider"); + //~ Methods ================================================================ + + public void testBadPassword() { + try { + jaasProvider.authenticate(new UsernamePasswordAuthenticationToken( + "user", "asdf")); + fail("LoginException should have been thrown for the bad password"); + } catch (AuthenticationException e) {} + + assertNotNull("Failure event not fired", eventCheck.failedEvent); + assertNotNull("Failure event exception was null", + eventCheck.failedEvent.getException()); + assertNull("Success event was fired", eventCheck.successEvent); + } + + public void testBadUser() { + try { + jaasProvider.authenticate(new UsernamePasswordAuthenticationToken( + "asdf", "password")); + fail("LoginException should have been thrown for the bad user"); + } catch (AuthenticationException e) {} + + assertNotNull("Failure event not fired", eventCheck.failedEvent); + assertNotNull("Failure event exception was null", + eventCheck.failedEvent.getException()); + assertNull("Success event was fired", eventCheck.successEvent); } public void testFull() throws Exception { - GrantedAuthorityImpl role1 = new GrantedAuthorityImpl("ROLE_1"); GrantedAuthorityImpl role2 = new GrantedAuthorityImpl("ROLE_2"); - GrantedAuthority[] defaultAuths = new GrantedAuthority[]{ - role1, - role2, - }; + GrantedAuthority[] defaultAuths = new GrantedAuthority[] {role1, role2,}; - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password", defaultAuths); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", + "password", defaultAuths); - assertTrue(jaasProvider.supports(UsernamePasswordAuthenticationToken.class)); + assertTrue(jaasProvider.supports( + UsernamePasswordAuthenticationToken.class)); Authentication auth = jaasProvider.authenticate(token); @@ -56,51 +93,41 @@ public class JaasAuthenticationProviderTests extends TestCase { List list = Arrays.asList(auth.getAuthorities()); assertTrue("GrantedAuthorities does not contain ROLE_TEST", - list.contains(new GrantedAuthorityImpl("ROLE_TEST"))); + list.contains(new GrantedAuthorityImpl("ROLE_TEST"))); - assertTrue("GrantedAuthorities does not contain ROLE_1", list.contains(role1)); + assertTrue("GrantedAuthorities does not contain ROLE_1", + list.contains(role1)); - assertTrue("GrantedAuthorities does not contain ROLE_2", list.contains(role2)); + assertTrue("GrantedAuthorities does not contain ROLE_2", + list.contains(role2)); boolean foundit = false; + for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); + if (obj instanceof JaasGrantedAuthority) { JaasGrantedAuthority grant = (JaasGrantedAuthority) obj; - assertNotNull("Principal was null on JaasGrantedAuthority", grant.getPrincipal()); + assertNotNull("Principal was null on JaasGrantedAuthority", + grant.getPrincipal()); foundit = true; } } + assertTrue("Could not find a JaasGrantedAuthority", foundit); assertNotNull("Success event not fired", eventCheck.successEvent); - assertEquals("Auth objects are not equal", auth, eventCheck.successEvent.getAuthentication()); + assertEquals("Auth objects are not equal", auth, + eventCheck.successEvent.getAuthentication()); assertNull("Failure event was fired", eventCheck.failedEvent); } - public void testBadUser() { - try { - jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("asdf", "password")); - fail("LoginException should have been thrown for the bad user"); - } catch (AuthenticationException e) { - } - - assertNotNull("Failure event not fired", eventCheck.failedEvent); - assertNotNull("Failure event exception was null", eventCheck.failedEvent.getException()); - assertNull("Success event was fired", eventCheck.successEvent); + protected void setUp() throws Exception { + String resName = "/" + getClass().getName().replace('.', '/') + ".xml"; + context = new ClassPathXmlApplicationContext(resName); + eventCheck = (JaasEventCheck) context.getBean("eventCheck"); + jaasProvider = (JaasAuthenticationProvider) context.getBean( + "jaasAuthenticationProvider"); } - - public void testBadPassword() { - try { - jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("user", "asdf")); - fail("LoginException should have been thrown for the bad password"); - } catch (AuthenticationException e) { - } - - assertNotNull("Failure event not fired", eventCheck.failedEvent); - assertNotNull("Failure event exception was null", eventCheck.failedEvent.getException()); - assertNull("Success event was fired", eventCheck.successEvent); - } - } diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml index d92876b877..8f243755ef 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml @@ -1,6 +1,8 @@ + +diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java b/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java index 2dc1260a48..1300467c49 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java @@ -1,25 +1,48 @@ +/* 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.providers.jaas.event.JaasAuthenticationFailedEvent; import net.sf.acegisecurity.providers.jaas.event.JaasAuthenticationSuccessEvent; + import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; + /** + * DOCUMENT ME! + * * @author Ray Krueger * @version $Id$ */ public class JaasEventCheck implements ApplicationListener { + //~ Instance fields ======================================================== JaasAuthenticationFailedEvent failedEvent; JaasAuthenticationSuccessEvent successEvent; + //~ Methods ================================================================ + public void onApplicationEvent(ApplicationEvent event) { - - if (event instanceof JaasAuthenticationFailedEvent) + if (event instanceof JaasAuthenticationFailedEvent) { failedEvent = (JaasAuthenticationFailedEvent) event; + } - if (event instanceof JaasAuthenticationSuccessEvent) + if (event instanceof JaasAuthenticationSuccessEvent) { successEvent = (JaasAuthenticationSuccessEvent) event; + } } } diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java index 774d563dce..8f1b5a9ea3 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java @@ -1,19 +1,39 @@ +/* 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 java.security.Principal; + /** - * Insert comments here... - *
+ * DOCUMENT ME! * * @author Ray Krueger * @version $Id$ */ public class TestAuthorityGranter implements AuthorityGranter { + //~ Methods ================================================================ + public String grant(Principal principal) { String role = null; - if (principal.getName().equals("TEST_PRINCIPAL")) + + if (principal.getName().equals("TEST_PRINCIPAL")) { role = "ROLE_TEST"; + } + return role; } } diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java index 1cb400426d..f694edf159 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java @@ -1,28 +1,48 @@ +/* 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.Authentication; +import java.io.IOException; + import javax.security.auth.callback.Callback; import javax.security.auth.callback.TextInputCallback; import javax.security.auth.callback.UnsupportedCallbackException; -import java.io.IOException; + /** - * Insert comments here... - *
+ * DOCUMENT ME! * * @author Ray Krueger * @version $Id$ */ public class TestCallbackHandler implements JaasAuthenticationCallbackHandler { + //~ Instance fields ======================================================== Authentication auth; + //~ Methods ================================================================ + public void setAuthentication(Authentication auth) { this.auth = auth; } - public void handle(Callback callback) throws IOException, UnsupportedCallbackException { + public void handle(Callback callback) + throws IOException, UnsupportedCallbackException { if (callback instanceof TextInputCallback) { TextInputCallback tic = (TextInputCallback) callback; tic.setText(auth.getPrincipal().toString()); diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java index 8dc412b5ea..95957a05c3 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java @@ -1,24 +1,44 @@ +/* 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 java.security.Principal; + +import java.util.Map; + import javax.security.auth.Subject; import javax.security.auth.callback.*; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import java.security.Principal; -import java.util.Map; + /** - * Insert comments here... - *
+ * DOCUMENT ME! * * @author Ray Krueger * @version $Id$ */ public class TestLoginModule implements LoginModule { + //~ Instance fields ======================================================== - private Subject subject; - private String user; private String password; + private String user; + private Subject subject; + + //~ Methods ================================================================ public boolean abort() throws LoginException { return true; @@ -28,8 +48,26 @@ public class TestLoginModule implements LoginModule { return true; } - public boolean login() throws LoginException { + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + this.subject = subject; + try { + TextInputCallback textCallback = new TextInputCallback("prompt"); + NameCallback nameCallback = new NameCallback("prompt"); + PasswordCallback passwordCallback = new PasswordCallback("prompt", + false); + + callbackHandler.handle(new Callback[] {textCallback, nameCallback, passwordCallback}); + + password = new String(passwordCallback.getPassword()); + user = nameCallback.getName(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public boolean login() throws LoginException { if (!user.equals("user")) { throw new LoginException("Bad User"); } @@ -39,38 +77,21 @@ public class TestLoginModule implements LoginModule { } subject.getPrincipals().add(new Principal() { - public String getName() { - return "TEST_PRINCIPAL"; - } - }); + public String getName() { + return "TEST_PRINCIPAL"; + } + }); subject.getPrincipals().add(new Principal() { - public String getName() { - return "NULL_PRINCIPAL"; - } - }); + public String getName() { + return "NULL_PRINCIPAL"; + } + }); + return true; } public boolean logout() throws LoginException { return true; } - - public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { - this.subject = subject; - try { - - TextInputCallback textCallback = new TextInputCallback("prompt"); - NameCallback nameCallback = new NameCallback("prompt"); - PasswordCallback passwordCallback = new PasswordCallback("prompt", false); - - callbackHandler.handle(new Callback[]{textCallback, nameCallback, passwordCallback}); - - password = new String(passwordCallback.getPassword()); - user = nameCallback.getName(); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } }