Jelajahi Sumber

Templated out event publishing. Added getApplicationContext(). Fixed javadoc formatting

Ray Krueger 20 tahun lalu
induk
melakukan
ec80ae22c1

+ 138 - 77
core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java

@@ -23,41 +23,49 @@ 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.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.InitializingBean;
+
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+
 import org.springframework.core.io.Resource;
+
 import org.springframework.util.Assert;
 
-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;
 
+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;
+
 
 /**
  * An {@link AuthenticationProvider} implementation that retrieves user details
  * from a JAAS login configuration.
- * <p/>
- * <p/>
+ * 
+ * <p>
  * This <code>AuthenticationProvider</code> is capable of validating {@link
  * net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken}
  * requests contain the correct username and password.
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * This implementation is backed by a <a
  * href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html">JAAS</a>
  * configuration. The loginConfig property must be set to a given JAAS
@@ -66,37 +74,37 @@ import java.util.Set;
  * configuration file containing an index matching the {@link
  * #setLoginContextName(java.lang.String) loginContextName} property.
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * For example: If this JaasAuthenticationProvider were configured in a Spring
  * WebApplicationContext the xml to set the loginConfiguration could be as
  * follows...
  * <pre>
- * &lt;property name="loginConfig"&gt;
- * &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
- * &lt;/property&gt;
- * </pre>
+ *  &lt;property name="loginConfig"&gt;
+ *  &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
+ *  &lt;/property&gt;
+ *  </pre>
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * The loginContextName should coincide with a given index in the loginConfig
  * specifed. The loginConfig file used in the JUnit tests appears as the
  * following...
  * <pre>
- * JAASTest {
- * net.sf.acegisecurity.providers.jaas.TestLoginModule required;
- * };
- * </pre>
+ *  JAASTest {
+ *  net.sf.acegisecurity.providers.jaas.TestLoginModule required;
+ *  };
+ *  </pre>
  * Using the example login configuration above, the loginContextName property
  * would be set as <i>JAASTest</i>...
  * <pre>
- * &lt;property name="loginContextName"&gt;
- * &lt;value&gt;JAASTest&lt;/value&gt;
- * &lt;/property&gt;
- * </pre>
+ *  &lt;property name="loginContextName"&gt;
+ *  &lt;value&gt;JAASTest&lt;/value&gt;
+ *  &lt;/property&gt;
+ *  </pre>
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * When using JAAS login modules as the authentication source, sometimes the <a
  * href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/LoginContext.html">LoginContext</a>
  * will require <i>CallbackHandler</i>s. The JaasAuthenticationProvider uses
@@ -107,24 +115,24 @@ import java.util.Set;
  * CallbackHandler, control is passed to each {@link
  * JaasAuthenticationCallbackHandler} for each Callback passed.
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * {{@link JaasAuthenticationCallbackHandler}s are passed to the
  * JaasAuthenticationProvider through the {@link
  * #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[])
  * callbackHandlers} property. }
  * <pre>
- * &lt;property name="callbackHandlers"&gt;
- * &lt;list&gt;
- * &lt;bean class="net.sf.acegisecurity.providers.jaas.TestCallbackHandler"/&gt;
- * &lt;bean class="{@link JaasNameCallbackHandler net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler}"/&gt;
- * &lt;bean class="{@link JaasPasswordCallbackHandler net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler}"/&gt;
- * &lt;/list&gt;
- * &lt;/property&gt;
- * </pre>
+ *  &lt;property name="callbackHandlers"&gt;
+ *  &lt;list&gt;
+ *  &lt;bean class="net.sf.acegisecurity.providers.jaas.TestCallbackHandler"/&gt;
+ *  &lt;bean class="{@link JaasNameCallbackHandler net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler}"/&gt;
+ *  &lt;bean class="{@link JaasPasswordCallbackHandler net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler}"/&gt;
+ *  &lt;/list&gt;
+ *  &lt;/property&gt;
+ *  </pre>
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * After calling LoginContext.login(), the JaasAuthenticationProvider will
  * retrieve the returned Principals from the Subject
  * (LoginContext.getSubject().getPrincipals). Each returned principal is then
@@ -135,26 +143,27 @@ import java.util.Set;
  * method. The returned role will be applied to the Authorization object as a
  * {@link GrantedAuthority}.
  * </p>
- * <p/>
- * <p/>
+ * 
+ * <p>
  * AuthorityGranters are configured in spring xml as follows...
  * <pre>
- * &lt;property name="authorityGranters"&gt;
- * &lt;list&gt;
- * &lt;bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
- * &lt;/list&gt;
- * &lt;/property&gt;
- * <p/>
- * </pre>
+ *  &lt;property name="authorityGranters"&gt;
+ *  &lt;list&gt;
+ *  &lt;bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
+ *  &lt;/list&gt;
+ *  &lt;/property&gt;
+ *  <p/>
+ *  </pre>
  * </p>
  *
  * @author Ray Krueger
  * @version $Id$
  */
 public class JaasAuthenticationProvider implements AuthenticationProvider,
-        InitializingBean, ApplicationContextAware {
+    InitializingBean, ApplicationContextAware {
+    //~ Static fields/initializers =============================================
 
-    private static final Log log = LogFactory.getLog(JaasAuthenticationProvider.class);
+    protected static final Log log = LogFactory.getLog(JaasAuthenticationProvider.class);
 
     //~ Instance fields ========================================================
 
@@ -169,15 +178,20 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
     //~ Methods ================================================================
 
     public void setApplicationContext(ApplicationContext applicationContext)
-            throws BeansException {
+        throws BeansException {
         this.context = applicationContext;
     }
 
+    public ApplicationContext getApplicationContext() {
+        return context;
+    }
+
     /**
      * 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) {
@@ -190,6 +204,7 @@ 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() {
@@ -202,7 +217,8 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
      *
      * @param callbackHandlers Array of JAASAuthenticationCallbackHandlers
      */
-    public void setCallbackHandlers(JaasAuthenticationCallbackHandler[] callbackHandlers) {
+    public void setCallbackHandlers(
+        JaasAuthenticationCallbackHandler[] callbackHandlers) {
         this.callbackHandlers = callbackHandlers;
     }
 
@@ -211,6 +227,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
      * none are set.
      *
      * @return the JAASAuthenticationCallbackHandlers.
+     *
      * @see #setCallbackHandlers(net.sf.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[])
      */
     public JaasAuthenticationCallbackHandler[] getCallbackHandlers() {
@@ -221,8 +238,9 @@ 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>
@@ -249,7 +267,8 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
         return loginContextName;
     }
 
-    public void setLoginExceptionResolver(LoginExceptionResolver loginExceptionResolver) {
+    public void setLoginExceptionResolver(
+        LoginExceptionResolver loginExceptionResolver) {
         this.loginExceptionResolver = loginExceptionResolver;
     }
 
@@ -258,31 +277,36 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
     }
 
     public void afterPropertiesSet() throws Exception {
-
-        Assert.notNull(loginConfig, "loginConfig must be set on "
-                + getClass());
-        Assert.hasLength(loginContextName, "loginContextName must be set on " + getClass());
+        Assert.notNull(loginConfig, "loginConfig must be set on " + getClass());
+        Assert.hasLength(loginContextName,
+            "loginContextName must be set on " + getClass());
 
         String loginConfigStr = null;
 
         try {
             loginConfigStr = loginConfig.getFile().toString();
         } catch (IOException e) {
-            log.debug("Could not resolve loginConfig [" + loginConfig + "] as a File, using URL");
+            if (log.isDebugEnabled()) {
+                log.debug("Could not resolve loginConfig [" + loginConfig
+                    + "] as a File, using URL");
+            }
+
             loginConfigStr = loginConfig.getURL().toString();
         }
 
-        boolean allowed = "true".equalsIgnoreCase(Security.getProperty("policy.allowSystemProperty"));
+        boolean allowed = "true".equalsIgnoreCase(Security.getProperty(
+                    "policy.allowSystemProperty"));
 
         if (allowed && (System.getProperty(SYSPROP) == null)) {
-            log.debug("Setting system property [" + SYSPROP + "] to: " + loginConfigStr);
+            log.debug("Setting system property [" + SYSPROP + "] to: "
+                + loginConfigStr);
             System.setProperty(SYSPROP, loginConfigStr);
         } else {
             setPropertyUsingLoop(loginConfigStr);
         }
 
         Assert.notNull(Configuration.getConfiguration(),
-                "As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html \"If a Configuration object was set via the Configuration.setConfiguration method, then that object is returned. Otherwise, a default Configuration object is returned\". Your JRE returned null to Configuration.getConfiguration().");
+            "As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html \"If a Configuration object was set via the Configuration.setConfiguration method, then that object is returned. Otherwise, a default Configuration object is returned\". Your JRE returned null to Configuration.getConfiguration().");
     }
 
     /**
@@ -290,17 +314,18 @@ 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;
 
@@ -323,7 +348,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++) {
@@ -339,18 +364,19 @@ 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));
+                publishSuccessEvent(token);
 
                 //we're done, return the token.
                 return token;
             } catch (LoginException loginException) {
                 AcegiSecurityException ase = loginExceptionResolver
-                        .resolveException(loginException);
+                    .resolveException(loginException);
 
-                context.publishEvent(new JaasAuthenticationFailedEvent(auth, ase));
+                publishFailureEvent(token, ase);
                 throw ase;
             }
         }
@@ -362,6 +388,40 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
         return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
     }
 
+    /**
+     * Publishes the {@link JaasAuthenticationFailedEvent}. Can be overridden
+     * by subclasses for different functionality
+     *
+     * @param token The {@link UsernamePasswordAuthenticationToken} being
+     *        processed
+     * @param ase The {@link AcegiSecurityException} that caused the failure
+     */
+    protected void publishFailureEvent(
+        UsernamePasswordAuthenticationToken token, AcegiSecurityException ase) {
+        getApplicationContext().publishEvent(new JaasAuthenticationFailedEvent(
+                token, ase));
+    }
+
+    /**
+     * Publishes the {@link JaasAuthenticationSuccessEvent}. Can be overridden
+     * by subclasses for different functionality.
+     *
+     * @param token The {@link UsernamePasswordAuthenticationToken} being
+     *        processed
+     */
+    protected void publishSuccessEvent(
+        UsernamePasswordAuthenticationToken token) {
+        getApplicationContext().publishEvent(new JaasAuthenticationSuccessEvent(
+                token));
+    }
+
+    /**
+     * Loops through the login.config.url.1,login.config.url.2 properties
+     * looking for the login configuration. If it is not set, it will be set
+     * to the last available login.config.url.X property.
+     *
+     * @param loginConfigStr
+     */
     private void setPropertyUsingLoop(String loginConfigStr) {
         boolean alreadySet = false;
 
@@ -381,7 +441,8 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
 
         if (!alreadySet) {
             String key = prefix + n;
-            log.debug("Setting security property [" + key + "] to: " + loginConfigStr);
+            log.debug("Setting security property [" + key + "] to: "
+                + loginConfigStr);
             Security.setProperty(key, loginConfigStr);
         }
     }
@@ -399,7 +460,7 @@ 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];
 

+ 4 - 0
core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java

@@ -199,6 +199,10 @@ public class JaasAuthenticationProviderTests extends TestCase {
                 auth.getAuthorities().length == 1);
     }
 
+    public void testGetApplicationContext() throws Exception {
+        assertNotNull(jaasProvider.getApplicationContext());
+    }
+
     public void testUnsupportedAuthenticationObjectReturnsNull() {
         assertNull(jaasProvider.authenticate(new TestingAuthenticationToken("foo", "bar",
                 new GrantedAuthority[]{})));