From 1947819d7303ac3a9f64b3e15444644d5c803f95 Mon Sep 17 00:00:00 2001 From: Ray Krueger Date: Mon, 19 Jul 2004 00:43:28 +0000 Subject: [PATCH] Adding in JAASAuthenticationProvider support --- .../providers/jaas/AuthorityGranter.java | 13 ++ .../JAASAuthenticationCallbackHandler.java | 20 +++ .../jaas/JAASAuthenticationProvider.java | 166 ++++++++++++++++++ .../providers/jaas/JAASGrantedAuthority.java | 25 +++ .../jaas/JAASNameCallbackHandler.java | 31 ++++ .../jaas/JAASPasswordCallbackHandler.java | 31 ++++ .../jaas/event/JAASAuthenticationEvent.java | 21 +++ .../event/JAASAuthenticationFailedEvent.java | 25 +++ .../event/JAASAuthenticationSuccessEvent.java | 18 ++ 9 files changed, 350 insertions(+) create mode 100644 core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java 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 diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java new file mode 100644 index 0000000000..155b278cf4 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java @@ -0,0 +1,13 @@ +package net.sf.acegisecurity.providers.jaas; + +import java.security.Principal; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public interface AuthorityGranter { + public String grant(Principal principal); +} 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..4a9c40e48c --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationCallbackHandler.java @@ -0,0 +1,20 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.IOException; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public interface JAASAuthenticationCallbackHandler { + void setAuthentication(Authentication auth); + 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..e852541b69 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationProvider.java @@ -0,0 +1,166 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.providers.jaas.event.JAASAuthenticationFailedEvent; +import net.sf.acegisecurity.providers.jaas.event.JAASAuthenticationSuccessEvent; +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.AuthorityGranter; +import net.sf.acegisecurity.providers.jaas.JAASAuthenticationCallbackHandler; +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.Subject; +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; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public class JAASAuthenticationProvider implements AuthenticationProvider, InitializingBean, ApplicationContextAware { + + private ApplicationContext context; + private String loginContextName = "ACEGI"; + private Resource loginConfig; + private JAASAuthenticationCallbackHandler[] callbackHandlers; + private AuthorityGranter[] authorityGranters; + + public Authentication authenticate(Authentication auth) throws AuthenticationException { + if (auth instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth; + + try { + + LoginContext lc = new LoginContext(loginContextName, new InternalCallbackHandler(auth)); + lc.login(); + + Set authorities = new HashSet(); + + if (token.getAuthorities() != null) { + authorities.addAll(Arrays.asList(token.getAuthorities())); + } + + Subject subject = lc.getSubject(); + + + Set principals = subject.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 (role != null) { + authorities.add(new JAASGrantedAuthority(role, principal)); + } + } + } + + token.setAuthorities((GrantedAuthority[]) authorities.toArray(new GrantedAuthority[authorities.size()])); + + context.publishEvent(new JAASAuthenticationSuccessEvent(token)); + + return token; + + } catch (LoginException e) { + context.publishEvent(new JAASAuthenticationFailedEvent(auth, e)); + 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; + } + + public void setLoginContextName(String loginContextName) { + this.loginContextName = loginContextName; + } + + public Resource getLoginConfig() { + return loginConfig; + } + + public void setLoginConfig(Resource loginConfig) throws IOException { + 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()); + } + + public JAASAuthenticationCallbackHandler[] getCallbackHandlers() { + return callbackHandlers; + } + + public void setCallbackHandlers(JAASAuthenticationCallbackHandler[] callbackHandlers) { + this.callbackHandlers = callbackHandlers; + } + + public AuthorityGranter[] getAuthorityGranters() { + return authorityGranters; + } + + public void setAuthorityGranters(AuthorityGranter[] authorityGranters) { + this.authorityGranters = authorityGranters; + } + + 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..e66f0a538b --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASGrantedAuthority.java @@ -0,0 +1,25 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.GrantedAuthorityImpl; + +import java.security.Principal; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public class JAASGrantedAuthority extends GrantedAuthorityImpl { + + 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..2f179e3ad3 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASNameCallbackHandler.java @@ -0,0 +1,31 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.providers.jaas.JAASAuthenticationCallbackHandler; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.IOException; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public class JAASNameCallbackHandler implements JAASAuthenticationCallbackHandler { + + private Authentication authentication; + + public void setAuthentication(Authentication authentication) { + this.authentication = authentication; + } + + 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..1e683bdda9 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASPasswordCallbackHandler.java @@ -0,0 +1,31 @@ +package net.sf.acegisecurity.providers.jaas; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.providers.jaas.JAASAuthenticationCallbackHandler; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.IOException; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public class JAASPasswordCallbackHandler implements JAASAuthenticationCallbackHandler { + + private Authentication auth; + + public void setAuthentication(Authentication auth) { + this.auth = auth; + } + + 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..d562a23cbf --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JAASAuthenticationEvent.java @@ -0,0 +1,21 @@ +package net.sf.acegisecurity.providers.jaas.event; + +import net.sf.acegisecurity.Authentication; +import org.springframework.context.ApplicationEvent; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public abstract class JAASAuthenticationEvent extends ApplicationEvent { + + public JAASAuthenticationEvent(Authentication auth) { + super(auth); + } + + 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..4d031ceb01 --- /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; +import net.sf.acegisecurity.providers.jaas.event.JAASAuthenticationEvent; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +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..589bfd09a7 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JAASAuthenticationSuccessEvent.java @@ -0,0 +1,18 @@ +package net.sf.acegisecurity.providers.jaas.event; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.providers.jaas.event.JAASAuthenticationEvent; + +/** + * Insert comments here... + *
+ * User: raykrueger@users.sourceforge.net
+ * Date: Jul 15, 2004
+ */ +public class JAASAuthenticationSuccessEvent extends JAASAuthenticationEvent { + + public JAASAuthenticationSuccessEvent(Authentication auth) { + super(auth); + } + +}