From 3360e2d51af193a13b9d2e33c6e96d3567835e16 Mon Sep 17 00:00:00 2001 From: Ray Krueger Date: Mon, 19 Jul 2004 17:24:38 +0000 Subject: [PATCH] Added in javadoc --- .../jaas/JAASAuthenticationProvider.java | 152 ++++++++++++++++-- 1 file changed, 138 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationProvider.java index e852541b69..1732142952 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JAASAuthenticationProvider.java @@ -1,15 +1,13 @@ 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 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; @@ -17,7 +15,6 @@ 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; @@ -32,10 +29,84 @@ import java.util.Iterator; import java.util.Set; /** - * Insert comments here... - *
- * User: raykrueger@users.sourceforge.net
- * Date: Jul 15, 2004
+ * 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 { @@ -45,44 +116,62 @@ public class JAASAuthenticationProvider implements AuthenticationProvider, Initi 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())); } - Subject subject = lc.getSubject(); - - - Set principals = subject.getPrincipals(); + //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()); } } @@ -101,6 +190,11 @@ public class JAASAuthenticationProvider implements AuthenticationProvider, Initi 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; } @@ -109,7 +203,13 @@ public class JAASAuthenticationProvider implements AuthenticationProvider, Initi return loginConfig; } - public void setLoginConfig(Resource loginConfig) throws IOException { + /** + * Set the JAAS login configuration file. + * + * @param loginConfig Spring Resource + * @see JAAS Reference + */ + public void setLoginConfig(Resource loginConfig) { this.loginConfig = loginConfig; } @@ -127,22 +227,46 @@ public class JAASAuthenticationProvider implements AuthenticationProvider, Initi 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;