You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by pl...@apache.org on 2010/02/01 12:27:04 UTC

svn commit: r905255 - in /incubator/shiro/trunk: support/spring/src/main/java/org/apache/shiro/spring/web/ support/spring/src/test/java/org/apache/shiro/spring/ web/src/main/java/org/apache/shiro/web/ web/src/main/java/org/apache/shiro/web/servlet/

Author: pledbrook
Date: Mon Feb  1 11:27:04 2010
New Revision: 905255

URL: http://svn.apache.org/viewvc?rev=905255&view=rev
Log:
Fix for SHIRO-130: I have introduced a WebSecurityManager interface that
the servlet filter classes use. This fixes the problem with proxies because
they can now proxy the new interface and provide the isHttpSessionMode()
method. This also fixes:

  http://jira.codehaus.org/browse/GRAILSPLUGINS-1742

Added:
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSecurityManager.java
Modified:
    incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
    incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/SpringShiroFilterTest.java
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java

Modified: incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java (original)
+++ incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean.java Mon Feb  1 11:27:04 2010
@@ -23,6 +23,7 @@
 import org.apache.shiro.util.CollectionUtils;
 import org.apache.shiro.util.Nameable;
 import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.web.WebSecurityManager;
 import org.apache.shiro.web.config.IniFilterChainResolverFactory;
 import org.apache.shiro.web.filter.AccessControlFilter;
 import org.apache.shiro.web.filter.authc.AuthenticationFilter;
@@ -423,6 +424,11 @@
             String msg = "SecurityManager property must be set.";
             throw new BeanInitializationException(msg);
         }
+        
+        if (!(securityManager instanceof WebSecurityManager)) {
+            String msg = "The security manager does not implement the WebSecurityManager interface.";
+            throw new BeanInitializationException(msg);
+        }
 
         FilterChainManager manager = createFilterChainManager();
 
@@ -437,7 +443,7 @@
         //here - we're just using it because it is a concrete ShiroFilter instance that accepts
         //injection of the SecurityManager and FilterChainResolver:
         IniShiroFilter shiroFilter = new IniShiroFilter();
-        shiroFilter.setSecurityManager(securityManager);
+        shiroFilter.setSecurityManager((WebSecurityManager) securityManager);
         shiroFilter.setFilterChainResolver(chainResolver);
 
         return shiroFilter;

Modified: incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/SpringShiroFilterTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/SpringShiroFilterTest.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/SpringShiroFilterTest.java (original)
+++ incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/SpringShiroFilterTest.java Mon Feb  1 11:27:04 2010
@@ -18,14 +18,22 @@
  */
 package org.apache.shiro.spring;
 
+import org.apache.shiro.config.ConfigurationException;
 import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.web.WebSecurityManager;
 import org.apache.shiro.web.servlet.ShiroFilter;
+
 import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import org.junit.Test;
 import org.springframework.web.context.WebApplicationContext;
 
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -49,7 +57,7 @@
 
         ServletContext mockContext = createMock(ServletContext.class);
         WebApplicationContext appCtx = createMock(WebApplicationContext.class);
-        SecurityManager secMgr = createMock(SecurityManager.class);
+        SecurityManager secMgr = createMock(WebSecurityManager.class);
         Map<String, org.apache.shiro.mgt.SecurityManager> beansOfType = new HashMap<String, SecurityManager>(1);
         beansOfType.put("securityManager", secMgr);
 
@@ -65,4 +73,43 @@
 
         filter.init(mockConfig);
     }
+    
+    @Test
+    public void testDefaultConfigWithNonWebSecurityManager() throws Exception {
+        SpringShiroFilter filter = new SpringShiroFilter();
+
+        FilterConfig mockConfig = createMock(FilterConfig.class);
+        expect(mockConfig.getInitParameter(ShiroFilter.CONFIG_CLASS_NAME_INIT_PARAM_NAME)).andReturn(null);
+        expect(mockConfig.getInitParameter(ShiroFilter.CONFIG_INIT_PARAM_NAME)).andReturn(null);
+        expect(mockConfig.getInitParameter(ShiroFilter.CONFIG_URL_INIT_PARAM_NAME)).andReturn(null);
+        expect(mockConfig.getInitParameter(SpringIniWebConfiguration.SECURITY_MANAGER_BEAN_NAME_PARAM_NAME)).andReturn(null);
+
+        ServletContext mockContext = createMock(ServletContext.class);
+        WebApplicationContext appCtx = createMock(WebApplicationContext.class);
+        SecurityManager secMgr = createMock(SecurityManager.class);
+        Map<String, org.apache.shiro.mgt.SecurityManager> beansOfType = new HashMap<String, SecurityManager>(1);
+        beansOfType.put("securityManager", secMgr);
+
+        expect(mockContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(appCtx);
+        expect(appCtx.getBeansOfType(SecurityManager.class)).andReturn(beansOfType);
+
+        expect(mockConfig.getServletContext()).andReturn(mockContext).anyTimes();
+
+
+        replay(mockContext);
+        replay(appCtx);
+        replay(mockConfig);
+
+        try {
+            filter.init(mockConfig);
+            fail("ServletException (wrapping a ConfigurationException) expected because the security manager " +
+                    "does not implement WebSecurityManager.");
+        }
+        catch (ServletException ex) {
+            // The cause should be a ConfigurationException.
+            assertTrue(
+                    "Original cause is not a ConfigurationException as expected",
+                    ex.getCause() instanceof ConfigurationException);
+        }
+    }
 }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java Mon Feb  1 11:27:04 2010
@@ -47,7 +47,7 @@
  * @author Les Hazlewood
  * @since 0.2
  */
-public class DefaultWebSecurityManager extends DefaultSecurityManager {
+public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager {
 
     //TODO - complete JavaDoc
 

Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSecurityManager.java?rev=905255&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSecurityManager.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebSecurityManager.java Mon Feb  1 11:27:04 2010
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shiro.web;
+
+import org.apache.shiro.mgt.SecurityManager;
+/**
+ * This interface represents a {@link SecurityManager} implementation that can
+ * be used in a servlet container.
+ *
+ * @author Peter Ledbrook
+ * @since 1.0
+ */
+public interface WebSecurityManager extends SecurityManager {
+    /**
+     * Security information needs to be retained from request to request, so Shiro makes use of a
+     * session for this. Typically, a security manager will use the servlet container's HTTP session
+     * but custom session implementations, for example based on EhCache, may also be used. This
+     * method indicates whether the security manager is using the HTTP session or not.
+     * @return <code>true</code> if the security manager is using the HTTP session; otherwise,
+     * <code>false</code>.
+     */
+    boolean isHttpSessionMode();
+}

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java Mon Feb  1 11:27:04 2010
@@ -19,12 +19,12 @@
 package org.apache.shiro.web.servlet;
 
 import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.ThreadContext;
 import org.apache.shiro.util.ThreadState;
 import org.apache.shiro.web.DefaultWebSecurityManager;
+import org.apache.shiro.web.WebSecurityManager;
 import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.filter.mgt.FilterChainResolver;
 import org.apache.shiro.web.subject.WebSubject;
@@ -57,7 +57,7 @@
     private static final Logger log = LoggerFactory.getLogger(AbstractShiroFilter.class);
 
     // Reference to the security manager used by this filter
-    private SecurityManager securityManager;
+    private WebSecurityManager securityManager;
 
     // Used to determine which chain should handle an incoming request/response
     private FilterChainResolver filterChainResolver;
@@ -65,11 +65,11 @@
     protected AbstractShiroFilter() {
     }
 
-    public SecurityManager getSecurityManager() {
+    public WebSecurityManager getSecurityManager() {
         return securityManager;
     }
 
-    public void setSecurityManager(SecurityManager sm) {
+    public void setSecurityManager(WebSecurityManager sm) {
         this.securityManager = sm;
     }
 
@@ -95,7 +95,7 @@
      * creates one automatically.
      */
     private void ensureSecurityManager() {
-        SecurityManager securityManager = getSecurityManager();
+        WebSecurityManager securityManager = getSecurityManager();
         if (securityManager == null) {
             log.info("No SecurityManager configured.  Creating default.");
             securityManager = createDefaultSecurityManager();
@@ -103,13 +103,12 @@
         }
     }
 
-    protected SecurityManager createDefaultSecurityManager() {
+    protected WebSecurityManager createDefaultSecurityManager() {
         return new DefaultWebSecurityManager();
     }
 
     protected boolean isHttpSessions() {
-        SecurityManager secMgr = getSecurityManager();
-        return !(secMgr instanceof DefaultWebSecurityManager) || ((DefaultWebSecurityManager) secMgr).isHttpSessionMode();
+        return getSecurityManager().isHttpSessionMode();
     }
 
     /**

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java Mon Feb  1 11:27:04 2010
@@ -18,10 +18,12 @@
  */
 package org.apache.shiro.web.servlet;
 
+import org.apache.shiro.config.ConfigurationException;
 import org.apache.shiro.config.Ini;
 import org.apache.shiro.config.IniFactorySupport;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.util.Factory;
+import org.apache.shiro.web.WebSecurityManager;
 import org.apache.shiro.web.config.IniFilterChainResolverFactory;
 import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
 import org.apache.shiro.web.filter.mgt.FilterChainResolver;
@@ -343,8 +345,17 @@
         } else {
             factory = new WebIniSecurityManagerFactory(ini);
         }
+        
+        // Create the security manager and check that it implements WebSecurityManager.
+        // Otherwise, it can't be used with the filter.
         SecurityManager securityManager = factory.getInstance();
-        setSecurityManager(securityManager);
+        if (!(securityManager instanceof WebSecurityManager)) {
+            String msg = "The configured security manager is not an instance of WebSecurityManager, so " +
+                    "it can not be used with the Shiro servlet filter.";
+            throw new ConfigurationException(msg);
+        }
+        
+        setSecurityManager((WebSecurityManager) securityManager);
     }
 
     protected void applyFilterChainResolver(Ini ini) {

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java?rev=905255&r1=905254&r2=905255&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroFilter.java Mon Feb  1 11:27:04 2010
@@ -30,6 +30,7 @@
 import org.apache.shiro.util.ThreadContext;
 import org.apache.shiro.util.ThreadState;
 import org.apache.shiro.web.DefaultWebSecurityManager;
+import org.apache.shiro.web.WebSecurityManager;
 import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.config.IniWebConfiguration;
 import org.apache.shiro.web.config.WebConfiguration;
@@ -254,7 +255,7 @@
     protected WebConfiguration configuration;
 
     // Reference to the security manager used by this filter
-    protected SecurityManager securityManager;
+    protected WebSecurityManager securityManager;
 
     // Used to determine which chain should handle an incoming request/response
     private FilterChainResolver filterChainResolver;
@@ -271,11 +272,11 @@
         this.configuration = configuration;
     }
 
-    public SecurityManager getSecurityManager() {
+    public WebSecurityManager getSecurityManager() {
         return securityManager;
     }
 
-    protected void setSecurityManager(SecurityManager sm) {
+    protected void setSecurityManager(WebSecurityManager sm) {
         this.securityManager = sm;
     }
 
@@ -302,10 +303,18 @@
      * @param config the configuration for this filter.
      */
     protected void ensureSecurityManager(Configuration config) {
-        SecurityManager securityManager = getSecurityManager();
+        WebSecurityManager securityManager = getSecurityManager();
         boolean existing = securityManager != null;
         if (!existing && config != null) {
-            securityManager = config.getSecurityManager();
+            // Get the configured security manager. If it isn't an implementation of
+            // WebSecurityManager, then we raise an error.
+            SecurityManager sm = config.getSecurityManager();
+            if (!(sm instanceof WebSecurityManager)) {
+                String msg = "The configured security manager is not an instance of WebSecurityManager, so " +
+                        "it can not be used with the Shiro servlet filter.";
+                throw new ConfigurationException(msg);
+            }
+            securityManager = (WebSecurityManager) sm;
         }
 
         // If the config doesn't return a security manager, build one by default.
@@ -420,8 +429,7 @@
     }
 
     protected boolean isHttpSessions() {
-        SecurityManager secMgr = getSecurityManager();
-        return !(secMgr instanceof DefaultWebSecurityManager) || ((DefaultWebSecurityManager) secMgr).isHttpSessionMode();
+        return getSecurityManager().isHttpSessionMode();
     }
 
     /**