瀏覽代碼

Added event for user context switching and updated switch user filter

Mark St. Godard 20 年之前
父節點
當前提交
20ebb668a6

+ 43 - 0
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationSwitchUserEvent.java

@@ -0,0 +1,43 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.providers.dao.event;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.UserDetails;
+
+
+/**
+ * Application event which indicates that a user context switch.
+ *
+ * @author Mark St.Godard
+ * @version $Id$
+ */
+public class AuthenticationSwitchUserEvent extends AuthenticationEvent {
+    //~ Constructors ===========================================================
+
+    /**
+     * Switch user context event constructor
+     *
+     * @param authentication The current <code>Authentication</code> object
+     * @param sourceUser The original user
+     * @param targetUser The target user
+     */
+    public AuthenticationSwitchUserEvent(Authentication authentication,
+        UserDetails targetUser) {
+        super(authentication, targetUser);
+    }
+
+}

+ 48 - 51
core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java

@@ -15,6 +15,20 @@
 
 package net.sf.acegisecurity.ui.switchuser;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import net.sf.acegisecurity.AccountExpiredException;
 import net.sf.acegisecurity.Authentication;
 import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
@@ -27,30 +41,17 @@ import net.sf.acegisecurity.context.SecurityContextHolder;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.AuthenticationDao;
 import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
+import net.sf.acegisecurity.providers.dao.event.AuthenticationSwitchUserEvent;
 import net.sf.acegisecurity.ui.WebAuthenticationDetails;
 
 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.util.Assert;
 
-import java.io.IOException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 
 /**
  * Switch User processing filter responsible for user context switching.
@@ -104,7 +105,8 @@ import javax.servlet.http.HttpServletResponse;
  *
  * @see net.sf.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
  */
-public class SwitchUserProcessingFilter implements InitializingBean, Filter {
+public class SwitchUserProcessingFilter implements Filter, InitializingBean,
+    ApplicationContextAware {
     //~ Static fields/initializers =============================================
 
     private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class);
@@ -112,19 +114,26 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
     // ~ Static fields/initializers
     // =============================================
     public static final String ACEGI_SECURITY_SWITCH_USERNAME_KEY = "j_username";
-    public static final String SWITCH_USER_GRANTED_AUTHORITY = "PREVIOUS_ADMINISTRATOR";
+    public static final String ROLE_PREVIOUS_ADMINISTRATOR = "ROLE_PREVIOUS_ADMINISTRATOR";
 
     //~ Instance fields ========================================================
 
+    private ApplicationContext context;
+
     // ~ Instance fields
     // ========================================================
     private AuthenticationDao authenticationDao;
-    private String exitUserUrl;
-    private String switchUserUrl;
+    private String exitUserUrl = "/j_acegi_exit_user";
+    private String switchUserUrl = "/j_acegi_switch_user";
     private String targetUrl;
 
     //~ Methods ================================================================
 
+    public void setApplicationContext(ApplicationContext context)
+        throws BeansException {
+        this.context = context;
+    }
+
     /**
      * Sets the authentication data access object.
      *
@@ -134,27 +143,6 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
         this.authenticationDao = authenticationDao;
     }
 
-    /**
-     * This filter by default responds to <code>/j_acegi_exit_user</code>.
-     *
-     * @return the default exit user url
-     */
-    public String getDefaultExitUserUrl() {
-        return "/j_acegi_exit_user";
-    }
-
-    // ~ Methods
-    // ================================================================
-
-    /**
-     * This filter by default responds to <code>/j_acegi_switch_user</code>.
-     *
-     * @return the default switch user url
-     */
-    public String getDefaultSwitchUserUrl() {
-        return "/j_acegi_switch_user";
-    }
-
     /**
      * Set the URL to respond to exit user processing.
      *
@@ -196,13 +184,9 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
      */
     public void doFilter(ServletRequest request, ServletResponse response,
         FilterChain chain) throws IOException, ServletException {
-        if (!(request instanceof HttpServletRequest)) {
-            throw new ServletException("Can only process HttpServletRequest");
-        }
-
-        if (!(response instanceof HttpServletResponse)) {
-            throw new ServletException("Can only process HttpServletResponse");
-        }
+    	
+    	Assert.isInstanceOf(HttpServletRequest.class,request);
+    	Assert.isInstanceOf(HttpServletResponse.class,response);
 
         HttpServletRequest httpRequest = (HttpServletRequest) request;
         HttpServletResponse httpResponse = (HttpServletResponse) response;
@@ -214,7 +198,7 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
 
             // update the current context to the new target user
             SecurityContextHolder.getContext().setAuthentication(targetUser);
-
+            
             // redirect to target url
             httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
 
@@ -268,6 +252,12 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
             throw new AuthenticationCredentialsNotFoundException(
                 "Could not find original Authentication object!");
         }
+        
+        // TODO: fix target user on exit
+        if (this.context != null) {
+            context.publishEvent(new AuthenticationSwitchUserEvent(
+            		current, null) );
+        }           
 
         return original;
     }
@@ -333,6 +323,13 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
             logger.debug("Switch User Token [" + targetUserRequest + "]");
         }
 
+        // publish event
+        if (this.context != null) {
+            context.publishEvent(new AuthenticationSwitchUserEvent(
+            		SecurityContextHolder.getContext().getAuthentication(),
+            		targetUser) );
+        }        
+        
         return targetUserRequest;
     }
 
@@ -437,7 +434,7 @@ public class SwitchUserProcessingFilter implements InitializingBean, Filter {
         // which will be used to 'exit' from the current switched user.
         Authentication currentAuth = SecurityContextHolder.getContext()
                                                           .getAuthentication();
-        GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(SWITCH_USER_GRANTED_AUTHORITY,
+        GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
                 currentAuth);
 
         // get the original authorities

+ 11 - 0
core/src/test/java/org/acegisecurity/providers/dao/event/AuthenticationEventTests.java

@@ -22,6 +22,7 @@ import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.User;
+import net.sf.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority;
 
 
 /**
@@ -88,6 +89,16 @@ public class AuthenticationEventTests extends TestCase {
         assertEquals(user, event.getUser());
     }
 
+    public void testSwitchUserContextEvent() {
+        Authentication auth = getAuthentication();
+        User targetUser = getUser();
+        
+        AuthenticationSwitchUserEvent event = new AuthenticationSwitchUserEvent(auth,
+                targetUser);
+        assertEquals(auth, event.getAuthentication());
+        assertEquals(targetUser, event.getUser());
+    }    
+    
     private Authentication getAuthentication() {
         UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal",
                 "Credentials");

+ 0 - 40
core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java

@@ -16,7 +16,6 @@
 package net.sf.acegisecurity.ui.switchuser;
 
 import junit.framework.TestCase;
-
 import net.sf.acegisecurity.AccountExpiredException;
 import net.sf.acegisecurity.Authentication;
 import net.sf.acegisecurity.AuthenticationException;
@@ -33,7 +32,6 @@ import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
 import net.sf.acegisecurity.util.MockFilterChain;
 
 import org.springframework.dao.DataAccessException;
-
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 
@@ -191,34 +189,6 @@ public class SwitchUserProcessingFilterTests extends TestCase {
         }
     }
 
-    public void testBadConfigMissingExitUserUrl() {
-        SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
-        filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
-        filter.setSwitchUserUrl("/j_acegi_switch_user");
-        filter.setTargetUrl("/main.jsp");
-
-        try {
-            filter.afterPropertiesSet();
-            fail("Expect to fail due to missing 'exitUserUrl'");
-        } catch (Exception expected) {
-            // expected exception
-        }
-    }
-
-    public void testBadConfigMissingSwitchUserUrl() {
-        SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
-        filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
-        filter.setExitUserUrl("/j_acegi_exit_user");
-        filter.setTargetUrl("/main.jsp");
-
-        try {
-            filter.afterPropertiesSet();
-            fail("Expect to fail due to missing 'switchUserUrl'");
-        } catch (Exception expected) {
-            // expected exception
-        }
-    }
-
     public void testBadConfigMissingTargetUrl() {
         SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
         filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
@@ -233,11 +203,6 @@ public class SwitchUserProcessingFilterTests extends TestCase {
         }
     }
 
-    public void testDefaultExitProcessUrl() {
-        SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
-        assertEquals("/j_acegi_exit_user", filter.getDefaultExitUserUrl());
-    }
-
     public void testDefaultProcessesFilterUrlWithPathParameter() {
         MockHttpServletRequest request = createMockSwitchRequest();
         SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
@@ -248,11 +213,6 @@ public class SwitchUserProcessingFilterTests extends TestCase {
         assertTrue(filter.requiresSwitchUser(request));
     }
 
-    public void testDefaultSwitchProcessUrl() {
-        SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
-        assertEquals("/j_acegi_switch_user", filter.getDefaultSwitchUserUrl());
-    }
-
     public void testExitRequestUserJackLordToDano() throws Exception {
         // original user	
         GrantedAuthority[] auths = {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(