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;