From f29e6763d4d1e33290b233efc7c5a167f10dad10 Mon Sep 17 00:00:00 2001 From: Ray Krueger Date: Wed, 28 Jul 2004 15:03:03 +0000 Subject: [PATCH] Renamed all JAAS* classes to Jaas* --- .../JaasAuthenticationCallbackHandler.java | 47 +++ .../jaas/JaasAuthenticationProvider.java | 290 ++++++++++++++++++ .../providers/jaas/JaasGrantedAuthority.java | 27 ++ .../jaas/JaasNameCallbackHandler.java | 43 +++ .../jaas/JaasPasswordCallbackHandler.java | 43 +++ .../jaas/event/JaasAuthenticationEvent.java | 31 ++ .../event/JaasAuthenticationFailedEvent.java | 25 ++ .../event/JaasAuthenticationSuccessEvent.java | 19 ++ .../jaas/JaasAuthenticationProviderTests.java | 71 +++++ .../jaas/JaasAuthenticationProviderTests.xml | 25 ++ .../providers/jaas/TestCallbackHandler.java | 2 +- 11 files changed, 622 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java create mode 100644 core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java new file mode 100644 index 0000000000..31acf54946 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java @@ -0,0 +1,47 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.IOException; + +/** + * The JaasAuthenticationCallbackHandler is similar to the javax.security.auth.callback.CallbackHandler interface + * in that it defines a handle method. The JaasAuthenticationCallbackHandler is only asked to handle one Callback instance at at time + * rather than an array of all Callbacks, as the javax... CallbackHandler defines. + *

+ * 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. + *

+ *
+ * + * @author Ray Krueger + * @version $Id$ + * @see JaasNameCallbackHandler + * @see JaasPasswordCallbackHandler + * @see Callback + * @see CallbackHandler + */ +public interface JaasAuthenticationCallbackHandler { + + /** + * Called by the JaasAuthenticationProvider before calling the handle method for any Callbacks. + * + * @param auth The Authentication object currently being authenticated. + */ + void setAuthentication(Authentication auth); + + /** + * Handle the Callback. + * The handle method will be called for every callback instance sent from the LoginContext. Meaning that The handle + * method may be called multiple times for a given JaasAuthenticationCallbackHandler, after a single call + * to the {@link #setAuthentication(net.sf.acegisecurity.Authentication) setAuthentication} method. + * + * @param callback + * @throws IOException + * @throws UnsupportedCallbackException + */ + void handle(Callback callback) throws IOException, UnsupportedCallbackException; + +} diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java new file mode 100644 index 0000000000..3037f73d31 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java @@ -0,0 +1,290 @@ +package net.sf.acegisecurity.providers.jaas; + +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; +import net.sf.acegisecurity.providers.jaas.event.JaasAuthenticationFailedEvent; +import net.sf.acegisecurity.providers.jaas.event.JaasAuthenticationSuccessEvent; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationContextException; +import org.springframework.core.io.Resource; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import java.io.IOException; +import java.security.Principal; +import java.security.Security; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * An {@link AuthenticationProvider} implementation that retrieves user details + * from a JAAS login configuration. + *

+ * This AuthenticationProvider is capable of validating {@link + * 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... + *

+ * JAASTest {
+ *   net.sf.acegisecurity.providers.jaas.TestLoginModule required;
+ * };
+ * 
+ * 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. + *

+ *

+ * {@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"/>
+ *           <bean class="{@link JaasNameCallbackHandler net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler}"/>
+ *           <bean class="{@link JaasPasswordCallbackHandler net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler}"/>
+ *       </list>
+ *   </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}. + *

+ * AuthorityGranters are configured in spring xml as follows... + *

+ * <property name="authorityGranters">
+ *   <list>
+ *       <bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/>
+ *   </list>
+ * </property>
+ * 

+ *

+ *

+ * + * @author Ray Krueger + * @version $Id$ + */ +public class JaasAuthenticationProvider implements AuthenticationProvider, InitializingBean, ApplicationContextAware { + + private ApplicationContext context; + private String loginContextName = "ACEGI"; + private Resource loginConfig; + private JaasAuthenticationCallbackHandler[] callbackHandlers; + private AuthorityGranter[] authorityGranters; + + /** + * 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. + */ + 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)); + + //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(); + + if (token.getAuthorities() != null) { + authorities.addAll(Arrays.asList(token.getAuthorities())); + } + + //get the subject principals and pass them to each of the AuthorityGranters + Set principals = lc.getSubject().getPrincipals(); + 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)); + } + } + } + + //Convert the authorities set back to an array and apply it to the token. + 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; + } + + public boolean supports(Class aClass) { + 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; + } + + + /** + * 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 { + + 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 new file mode 100644 index 0000000000..fb9727fb21 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java @@ -0,0 +1,27 @@ +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. + *
+ * + * @author Ray Krueger + * @version $Id$ + * @see AuthorityGranter + */ +public class JaasGrantedAuthority extends GrantedAuthorityImpl { + + private Principal principal; + + public JaasGrantedAuthority(String role, Principal principal) { + super(role); + this.principal = principal; + } + + 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 new file mode 100644 index 0000000000..0494a8048d --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java @@ -0,0 +1,43 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; + +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. + *
+ * + * @author Ray Krueger + * @version $Id$ + * @see Callback + * @see NameCallback + */ +public class JaasNameCallbackHandler implements JaasAuthenticationCallbackHandler { + + private Authentication authentication; + + 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. + * + * @param callback + * @throws IOException + * @throws 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 new file mode 100644 index 0000000000..2f1da331b9 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java @@ -0,0 +1,43 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; + +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. + *
+ * + * @author Ray Krueger + * @version $Id$ + * @see Callback + * @see PasswordCallback + */ +public class JaasPasswordCallbackHandler implements JaasAuthenticationCallbackHandler { + + private Authentication auth; + + 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. + * + * @param callback + * @throws IOException + * @throws 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/JaasAuthenticationEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java new file mode 100644 index 0000000000..15e9d26f29 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java @@ -0,0 +1,31 @@ +package net.sf.acegisecurity.providers.jaas.event; + +import net.sf.acegisecurity.Authentication; +import org.springframework.context.ApplicationEvent; + +/** + * Parent class for events fired by the {@link net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider JaasAuthenticationProvider}. + * + * @author Ray Krueger + * @version $Id$ + */ +public abstract class JaasAuthenticationEvent extends ApplicationEvent { + + /** + * The Authentication object is stored as the ApplicationEvent 'source'. + * + * @param auth + */ + public JaasAuthenticationEvent(Authentication auth) { + super(auth); + } + + /** + * Pre-casted method that returns the 'source' of the event. + * + * @return + */ + public Authentication getAuthentication() { + return (Authentication) source; + } +} 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 new file mode 100644 index 0000000000..12e73383e7 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java @@ -0,0 +1,25 @@ +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. + *
+ * + * @author Ray Krueger + * @version $Id$ + */ +public class JaasAuthenticationFailedEvent extends JaasAuthenticationEvent { + + private Exception exception; + + public JaasAuthenticationFailedEvent(Authentication auth, Exception exception) { + super(auth); + this.exception = exception; + } + + 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 new file mode 100644 index 0000000000..5d13c43329 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java @@ -0,0 +1,19 @@ +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. + *
+ * + * @author Ray Krueger + * @version $Id$ + */ +public class JaasAuthenticationSuccessEvent extends JaasAuthenticationEvent { + + 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 new file mode 100644 index 0000000000..e00c0d4eb1 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java @@ -0,0 +1,71 @@ +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.support.FileSystemXmlApplicationContext; + +import java.util.Arrays; +import java.util.List; + +/** + * Insert comments here... + *
+ * + * @author Ray Krueger + * @version $Id$ + */ +public class JaasAuthenticationProviderTests extends TestCase { + + private JaasAuthenticationProvider jaasProvider; + + protected void setUp() throws Exception { + String resName = "/" + getClass().getName().replace('.', '/') + ".xml"; + FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(getClass().getResource(resName).toString()); + jaasProvider = (JaasAuthenticationProvider) context.getBean("jaasAuthenticationProvider"); + } + + public void testFull() throws Exception { + + GrantedAuthorityImpl role1 = new GrantedAuthorityImpl("ROLE_1"); + GrantedAuthorityImpl role2 = new GrantedAuthorityImpl("ROLE_2"); + + GrantedAuthority[] defaultAuths = new GrantedAuthority[]{ + role1, + role2, + }; + + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password", defaultAuths); + + Authentication auth = jaasProvider.authenticate(token); + + List list = Arrays.asList(auth.getAuthorities()); + + assertTrue("GrantedAuthorities does not contain ROLE_TEST", + list.contains(new GrantedAuthorityImpl("ROLE_TEST"))); + + assertTrue("GrantedAuthorities does not contain ROLE_1", list.contains(role1)); + + assertTrue("GrantedAuthorities does not contain ROLE_2", list.contains(role2)); + } + + public void testBadUser() { + try { + jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("asdf", "password")); + fail("LoginException should have been thrown for the bad user"); + } catch (AuthenticationException e) { + } + } + + public void testBadPassword() { + try { + jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("user", "asdf")); + fail("LoginException should have been thrown for the bad password"); + } catch (AuthenticationException e) { + } + } + +} diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml new file mode 100644 index 0000000000..e9d37156cb --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.xml @@ -0,0 +1,25 @@ + + + + + + + JAASTest + + + classpath:net/sf/acegisecurity/providers/jaas/login.conf + + + + + + + + + + + + + + + \ No newline at end of file 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 199174d77e..15cc82a798 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java @@ -14,7 +14,7 @@ import java.io.IOException; * @author Ray Krueger * @version $Id$ */ -public class TestCallbackHandler implements JAASAuthenticationCallbackHandler { +public class TestCallbackHandler implements JaasAuthenticationCallbackHandler { Authentication auth;