The JaasAuthenticationCallbackHandler handle method now takes a callback and the authentication in progress, the setAuthentication method has been removed.

The JaasAuthenticationProvider afterPropertiesSet method now makes use of the java.security.auth.login.config System property before trying to use the login.config.url.X properties.
This commit is contained in:
Ray Krueger 2005-01-31 05:16:32 +00:00
parent 358056bf4d
commit 82c15b1874
7 changed files with 99 additions and 105 deletions

View File

@ -50,29 +50,19 @@ import javax.security.auth.callback.UnsupportedCallbackException;
public interface JaasAuthenticationCallbackHandler {
//~ Methods ================================================================
/**
* 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 <a
* href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/callback/Callback.html">Callback</a>.
* 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.
* times for a given JaasAuthenticationCallbackHandler.
*
* @param callback
* @param auth The Authentication object currently being authenticated.
*
* @throws IOException
* @throws UnsupportedCallbackException
*/
void handle(Callback callback)
void handle(Callback callback, Authentication auth)
throws IOException, UnsupportedCallbackException;
}

View File

@ -15,6 +15,7 @@
package net.sf.acegisecurity.providers.jaas;
import com.sun.security.auth.login.ConfigFile;
import net.sf.acegisecurity.AcegiSecurityException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationException;
@ -23,31 +24,26 @@ 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 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;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.Configuration;
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;
/**
@ -155,7 +151,7 @@ import javax.security.auth.login.LoginException;
* @version $Id$
*/
public class JaasAuthenticationProvider implements AuthenticationProvider,
InitializingBean, ApplicationContextAware {
InitializingBean, ApplicationContextAware {
//~ Instance fields ========================================================
private ApplicationContext context;
@ -164,11 +160,12 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
private String loginContextName = "ACEGI";
private AuthorityGranter[] authorityGranters;
private JaasAuthenticationCallbackHandler[] callbackHandlers;
private final String SYSPROP = "java.security.auth.login.config";
//~ Methods ================================================================
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
throws BeansException {
this.context = applicationContext;
}
@ -177,7 +174,6 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
* granted to the Authentication.
*
* @param authorityGranters AuthorityGranter array
*
* @see JaasAuthenticationProvider
*/
public void setAuthorityGranters(AuthorityGranter[] authorityGranters) {
@ -190,7 +186,6 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
* were ever set.
*
* @return The AuthorityGranter array, or null
*
* @see #setAuthorityGranters(net.sf.acegisecurity.providers.jaas.AuthorityGranter[])
*/
public AuthorityGranter[] getAuthorityGranters() {
@ -203,8 +198,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
*
* @param callbackHandlers Array of JAASAuthenticationCallbackHandlers
*/
public void setCallbackHandlers(
JaasAuthenticationCallbackHandler[] callbackHandlers) {
public void setCallbackHandlers(JaasAuthenticationCallbackHandler[] callbackHandlers) {
this.callbackHandlers = callbackHandlers;
}
@ -213,7 +207,6 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
* none are set.
*
* @return the JAASAuthenticationCallbackHandlers.
*
* @see #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[])
*/
public JaasAuthenticationCallbackHandler[] getCallbackHandlers() {
@ -224,9 +217,8 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
* Set the JAAS login configuration file.
*
* @param loginConfig <a
* href="http://www.springframework.org/docs/api/org/springframework/core/io/Resource.html">Spring
* Resource</a>
*
* href="http://www.springframework.org/docs/api/org/springframework/core/io/Resource.html">Spring
* Resource</a>
* @see <a
* href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html">JAAS
* Reference</a>
@ -253,8 +245,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
return loginContextName;
}
public void setLoginExceptionResolver(
LoginExceptionResolver loginExceptionResolver) {
public void setLoginExceptionResolver(LoginExceptionResolver loginExceptionResolver) {
this.loginExceptionResolver = loginExceptionResolver;
}
@ -265,22 +256,24 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
public void afterPropertiesSet() throws Exception {
if (loginConfig == null) {
throw new ApplicationContextException("loginConfig must be set on "
+ getClass());
+ getClass());
}
if ((loginContextName == null) || "".equals(loginContextName)) {
throw new ApplicationContextException(
"loginContextName must be set on " + getClass());
throw new ApplicationContextException("loginContextName must be set on " + getClass());
}
int n = 1;
String loginConfigStr = loginConfig.getURL().toString();
while (Security.getProperty("login.config.url." + n) != null) {
n++;
boolean allowed = "true".equalsIgnoreCase(Security.getProperty("policy.allowSystemProperty"));
if (allowed) {
System.setProperty(SYSPROP, loginConfigStr);
} else {
setPropertyUsingLoop(loginConfigStr);
}
Security.setProperty("login.config.url." + n,
loginConfig.getURL().toString());
Configuration.setConfiguration(new ConfigFile());
}
/**
@ -288,18 +281,16 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
* 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.
* '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 {
throws AuthenticationException {
if (auth instanceof UsernamePasswordAuthenticationToken) {
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth;
@ -322,7 +313,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
Set principals = lc.getSubject().getPrincipals();
for (Iterator iterator = principals.iterator();
iterator.hasNext();) {
iterator.hasNext();) {
Principal principal = (Principal) iterator.next();
for (int i = 0; i < authorityGranters.length; i++) {
@ -338,8 +329,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
}
//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));
@ -348,7 +338,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
return token;
} catch (LoginException loginException) {
AcegiSecurityException ase = loginExceptionResolver
.resolveException(loginException);
.resolveException(loginException);
context.publishEvent(new JaasAuthenticationFailedEvent(auth, ase));
throw ase;
@ -362,6 +352,28 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
}
private void setPropertyUsingLoop(String loginConfigStr) {
boolean alreadySet = false;
int n = 1;
String prefix = "login.config.url.";
String existing = null;
while ((existing = Security.getProperty(prefix + n)) != null) {
alreadySet = existing.equals(loginConfigStr);
if (alreadySet) {
break;
}
n++;
}
if (!alreadySet) {
Security.setProperty(prefix + n, loginConfigStr);
}
}
//~ Inner Classes ==========================================================
/**
@ -375,16 +387,14 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
}
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
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);
handler.handle(callback, authentication);
}
}
}

View File

@ -40,30 +40,20 @@ import javax.security.auth.callback.UnsupportedCallbackException;
*/
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.
* callback.setName(authentication.getPrincipal().toString()).
*
* @param callback
* @param authentication
*
* @throws IOException
* @throws UnsupportedCallbackException
*/
public void handle(Callback callback)
public void handle(Callback callback, Authentication authentication)
throws IOException, UnsupportedCallbackException {
if (callback instanceof NameCallback) {
NameCallback ncb = (NameCallback) callback;

View File

@ -40,31 +40,20 @@ import javax.security.auth.callback.UnsupportedCallbackException;
*/
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.
* callback.setPassword(authentication.getCredentials().toString()).
*
* @param callback
* @param auth
*
* @throws IOException
* @throws UnsupportedCallbackException
*/
public void handle(Callback callback)
public void handle(Callback callback, Authentication auth)
throws IOException, UnsupportedCallbackException {
if (callback instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callback;

View File

@ -17,7 +17,12 @@ package net.sf.acegisecurity.providers.jaas;
import junit.framework.TestCase;
import net.sf.acegisecurity.*;
import net.sf.acegisecurity.AcegiSecurityException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.LockedException;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
@ -25,6 +30,10 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.net.URL;
import java.security.Security;
import java.util.Arrays;
import java.util.List;
@ -72,6 +81,17 @@ public class JaasAuthenticationProviderTests extends TestCase {
assertNull("Success event was fired", eventCheck.successEvent);
}
public void testConfigurationLoop() throws Exception {
String resName = "/" + getClass().getName().replace('.', '/') + ".conf";
URL url = getClass().getResource(resName);
Security.setProperty("policy.allowSystemProperty", "false");
Security.setProperty("login.config.url.1", url.toString());
setUp();
testFull();
}
public void testDetectsMissingLoginConfig() throws Exception {
JaasAuthenticationProvider myJaasProvider = new JaasAuthenticationProvider();
myJaasProvider.setApplicationContext(context);

View File

@ -25,23 +25,15 @@ import javax.security.auth.callback.UnsupportedCallbackException;
/**
* DOCUMENT ME!
* TestCallbackHandler
*
* @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)
public void handle(Callback callback, Authentication auth)
throws IOException, UnsupportedCallbackException {
if (callback instanceof TextInputCallback) {
TextInputCallback tic = (TextInputCallback) callback;

View File

@ -0,0 +1,3 @@
JAASTest2 {
net.sf.acegisecurity.providers.jaas.TestLoginModule required;
};