You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2009/09/12 01:00:26 UTC
svn commit: r814073 - in /incubator/shiro/trunk: ./
core/src/main/java/org/apache/shiro/mgt/
core/src/main/java/org/apache/shiro/util/ samples/spring-hibernate/
samples/spring/ samples/web/ support/ support/groovy/ support/groovy/src/
support/groovy/sr...
Author: lhazlewood
Date: Fri Sep 11 23:00:25 2009
New Revision: 814073
URL: http://svn.apache.org/viewvc?rev=814073&view=rev
Log:
Began initial 'composition over inheritance' support for configuration. None of the additions are used in existing code yet - they are there as placeholders only at the moment to be used later when refactoring existing components (e.g. IniWebConfiguration)
Added:
incubator/shiro/trunk/support/groovy/ (with props)
incubator/shiro/trunk/support/groovy/pom.xml
incubator/shiro/trunk/support/groovy/src/
incubator/shiro/trunk/support/groovy/src/main/
incubator/shiro/trunk/support/groovy/src/main/java/
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/DefaultFilterChainManager.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainManager.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainResolver.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/NamedFilterList.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilterChainResolver.java
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/SimpleNamedFilterList.java
Modified:
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/RealmSecurityManager.java
incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/CollectionUtils.java
incubator/shiro/trunk/pom.xml
incubator/shiro/trunk/samples/spring-hibernate/pom.xml
incubator/shiro/trunk/samples/spring/pom.xml
incubator/shiro/trunk/samples/web/pom.xml
incubator/shiro/trunk/support/pom.xml
incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/config/WebConfiguration.java
incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/RealmSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/RealmSecurityManager.java?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/RealmSecurityManager.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/RealmSecurityManager.java Fri Sep 11 23:00:25 2009
@@ -18,14 +18,14 @@
*/
package org.apache.shiro.mgt;
-import java.util.ArrayList;
-import java.util.Collection;
-
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.CacheManagerAware;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.LifecycleUtils;
+import java.util.ArrayList;
+import java.util.Collection;
+
/**
* Shiro support of a {@link SecurityManager} class hierarchy based around a collection of
@@ -110,7 +110,7 @@
protected void applyCacheManagerToRealms() {
CacheManager cacheManager = getCacheManager();
Collection<Realm> realms = getRealms();
- if (realms != null && !realms.isEmpty()) {
+ if (cacheManager != null && realms != null && !realms.isEmpty()) {
for (Realm realm : realms) {
if (realm instanceof CacheManagerAware) {
((CacheManagerAware) realm).setCacheManager(cacheManager);
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/CollectionUtils.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/CollectionUtils.java?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/CollectionUtils.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/CollectionUtils.java Fri Sep 11 23:00:25 2009
@@ -18,12 +18,7 @@
*/
package org.apache.shiro.util;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
/**
* Static helper class for use dealing with Arrays.
@@ -59,6 +54,24 @@
return set;
}
+ /**
+ * @param c
+ * @return
+ * @since 1.0
+ */
+ public static boolean isEmpty(Collection c) {
+ return c == null || c.isEmpty();
+ }
+
+ /**
+ * @param m
+ * @return
+ * @since 1.0
+ */
+ public static boolean isEmpty(Map m) {
+ return m == null || m.isEmpty();
+ }
+
@SuppressWarnings({"unchecked"})
public static <E> List<E> asList(E... elements) {
if (elements == null || elements.length == 0) {
Modified: incubator/shiro/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/pom.xml?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/pom.xml (original)
+++ incubator/shiro/trunk/pom.xml Fri Sep 11 23:00:25 2009
@@ -59,9 +59,10 @@
<properties>
<jdk.version>1.5</jdk.version>
<slf4j.version>1.5.6</slf4j.version>
- <hsqldbVersion>1.8.0.7</hsqldbVersion>
- <jettyVersion>6.1.20</jettyVersion>
- <springframeworkVersion>2.5.6</springframeworkVersion>
+ <hsqldb.version>1.8.0.7</hsqldb.version>
+ <jetty.version>6.1.20</jetty.version>
+ <spring.version>2.5.6</spring.version>
+ <groovy.version>1.6.2</groovy.version>
</properties>
<modules>
@@ -176,7 +177,7 @@
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
- <version>${hsqldbVersion}</version>
+ <version>${hsqldb.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
@@ -218,6 +219,11 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.4.1</version>
@@ -302,7 +308,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
- <version>${springframeworkVersion}</version>
+ <version>${spring.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
@@ -314,7 +320,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
- <version>${springframeworkVersion}</version>
+ <version>${spring.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
Modified: incubator/shiro/trunk/samples/spring-hibernate/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/spring-hibernate/pom.xml?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/samples/spring-hibernate/pom.xml (original)
+++ incubator/shiro/trunk/samples/spring-hibernate/pom.xml Fri Sep 11 23:00:25 2009
@@ -37,7 +37,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
- <version>${jettyVersion}</version>
+ <version>${jetty.version}</version>
<!-- <configuration>
<contextPath>/shirosprhib</contextPath>
<connectors>
@@ -68,7 +68,7 @@
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
- <version>${hsqldbVersion}</version>
+ <version>${hsqldb.version}</version>
</dependency>
</dependencies> -->
</plugin>
Modified: incubator/shiro/trunk/samples/spring/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/spring/pom.xml?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/samples/spring/pom.xml (original)
+++ incubator/shiro/trunk/samples/spring/pom.xml Fri Sep 11 23:00:25 2009
@@ -37,7 +37,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
- <version>${jettyVersion}</version>
+ <version>${jetty.version}</version>
<configuration>
<contextPath>/shiro</contextPath>
<connectors>
@@ -58,7 +58,7 @@
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
- <version>${hsqldbVersion}</version>
+ <version>${hsqldb.version}</version>
</dependency>
</dependencies>
</plugin>
@@ -109,7 +109,7 @@
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
- <version>${hsqldbVersion}</version>
+ <version>${hsqldb.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
Modified: incubator/shiro/trunk/samples/web/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/web/pom.xml?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/samples/web/pom.xml (original)
+++ incubator/shiro/trunk/samples/web/pom.xml Fri Sep 11 23:00:25 2009
@@ -43,7 +43,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
- <version>${jettyVersion}</version>
+ <version>${jetty.version}</version>
<configuration>
<contextPath>/</contextPath>
<connectors>
@@ -101,13 +101,13 @@
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
- <version>${jettyVersion}</version>
+ <version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-jetty</artifactId>
- <version>${jettyVersion}</version>
+ <version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Propchange: incubator/shiro/trunk/support/groovy/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Sep 11 23:00:25 2009
@@ -0,0 +1 @@
+*.iml
Added: incubator/shiro/trunk/support/groovy/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/groovy/pom.xml?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/support/groovy/pom.xml (added)
+++ incubator/shiro/trunk/support/groovy/pom.xml Fri Sep 11 23:00:25 2009
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-root</artifactId>
+ <version>1.0-incubating-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shiro-groovy</artifactId>
+ <name>Apache Shiro :: Support :: Groovy</name>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ </dependency>
+ <!-- Test dependencies -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Modified: incubator/shiro/trunk/support/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/pom.xml?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/support/pom.xml (original)
+++ incubator/shiro/trunk/support/pom.xml Fri Sep 11 23:00:25 2009
@@ -33,6 +33,7 @@
<modules>
<module>ehcache</module>
+ <module>groovy</module>
<module>quartz</module>
<module>spring</module>
</modules>
Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/config/WebConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/config/WebConfiguration.java?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/config/WebConfiguration.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/config/WebConfiguration.java Fri Sep 11 23:00:25 2009
@@ -19,40 +19,16 @@
package org.apache.shiro.web.config;
import org.apache.shiro.config.Configuration;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import org.apache.shiro.web.filter.FilterChainResolver;
/**
- * A <code>WebConfiguration</code> configures Shiro components in a web-enabled application.
- * <p/>
- * In addition to enabling configuration of a <code>SecurityManager</code>, as required by the parent interface,
- * it also allows configuration of arbitrary filter chains to be executed for any given request or URI/URL.
+ * A {@code WebConfiguration} configures Shiro components in a web-enabled application.
* <p/>
- * This is incredibly powerful and <em>much</em> more flexible than normal servlet filter definitions or Servlet
- * security: it allows arbitrary filter chains to be defined per URL in a much more concise and easy to read manner,
- * and even allows filter chains to be dynamically resolved or construtected at runtime if the underlying implementation
- * supports it.
+ * In addition to enabling configuration of a <code>SecurityManager</code>, as required by the parent
+ * {@link Configuration} interface, it also allows configuration of arbitrary filter chains to be executed for any
+ * given request or URI/URL by sub-interfacing the {@link FilterChainResolver} interface.
*
- * @author Les Hazlewood
- * @since Jun 1, 2008 11:13:32 PM
+ * @since 0.9
*/
-public interface WebConfiguration extends Configuration {
-
- /**
- * Returns the filter chain that should be executed for the given request, or <code>null</code> if the
- * original chain should be used.
- *
- * <p>This method allows a Configuration implementation to define arbitrary security {@link Filter Filter}
- * chains for any given request or URL pattern.
- *
- * @param request the incoming ServletRequest
- * @param response the outgoing ServletResponse
- * @param originalChain the original <code>FilterChain</code> intercepted by the ShiroFilter.
- * @return the filter chain that should be executed for the given request, or <code>null</code> if the
- * original chain should be used.
- */
- FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);
+public interface WebConfiguration extends Configuration, FilterChainResolver {
}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/DefaultFilterChainManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/DefaultFilterChainManager.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/DefaultFilterChainManager.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/DefaultFilterChainManager.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,281 @@
+/*
+ * 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.filter;
+
+import org.apache.shiro.ShiroException;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.util.CollectionUtils;
+import org.apache.shiro.util.Initializable;
+import org.apache.shiro.util.Nameable;
+import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.web.filter.authc.AnonymousFilter;
+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
+import org.apache.shiro.web.filter.authc.UserFilter;
+import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
+import org.apache.shiro.web.filter.authz.PortFilter;
+import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
+import org.apache.shiro.web.filter.authz.SslFilter;
+import org.apache.shiro.web.servlet.ProxiedFilterChain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import java.util.*;
+
+/**
+ * @since 1.0
+ */
+public class DefaultFilterChainManager implements FilterChainManager, Initializable {
+
+ private static transient final Logger log = LoggerFactory.getLogger(DefaultFilterChainManager.class);
+
+ private FilterConfig filterConfig;
+
+ private Map<String, Filter> filters; //pool of filters available for creating filters
+
+ private Map<String, NamedFilterList> filterChains; //name to filter chain mapping
+
+ public DefaultFilterChainManager() {
+ this.filters = new LinkedHashMap<String, Filter>();
+ this.filterChains = new LinkedHashMap<String, NamedFilterList>();
+ }
+
+ public DefaultFilterChainManager(FilterConfig filterConfig) {
+ this();
+ init(filterConfig);
+ }
+
+ /**
+ * Returns the {@code FilterConfig} provided by the Servlet container at webapp startup.
+ *
+ * @return the {@code FilterConfig} provided by the Servlet container at webapp startup.
+ */
+ public FilterConfig getFilterConfig() {
+ return filterConfig;
+ }
+
+ /**
+ * Sets the {@code FilterConfig} provided by the Servlet container at webapp startup.
+ *
+ * @param filterConfig the {@code FilterConfig} provided by the Servlet container at webapp startup.
+ */
+ public void setFilterConfig(FilterConfig filterConfig) {
+ this.filterConfig = filterConfig;
+ }
+
+ public Map<String, Filter> getFilters() {
+ return filters;
+ }
+
+ public void setFilters(Map<String, Filter> filters) {
+ this.filters = filters;
+ }
+
+ public Map<String, NamedFilterList> getFilterChains() {
+ return filterChains;
+ }
+
+ public void setFilterChains(Map<String, NamedFilterList> filterChains) {
+ this.filterChains = filterChains;
+ }
+
+ public void init() throws ShiroException {
+ if (this.filterConfig == null) {
+ throw new IllegalStateException("filterConfig attribute must be set.");
+ }
+ addDefaultFilters();
+ }
+
+ public void init(FilterConfig filterConfig) throws ShiroException {
+ setFilterConfig(filterConfig);
+ init();
+ }
+
+ public Filter getFilter(String name) {
+ return this.filters.get(name);
+ }
+
+ public void addFilter(String name, Filter filter) {
+ addFilter(name, filter, true);
+ }
+
+ public void addFilter(String name, Filter filter, boolean init) {
+ addFilter(name, filter, init, true);
+ }
+
+ protected void addFilter(String name, Filter filter, boolean init, boolean overwrite) {
+ Filter existing = getFilter(name);
+ if (existing == null || overwrite) {
+ if (init) {
+ initFilter(filter);
+ }
+ this.filters.put(name, filter);
+ }
+ }
+
+ public void addToChain(String chainName, String filterName) {
+ addToChain(chainName, filterName, null);
+ }
+
+ protected void applyChainConfig(String chainName, Filter filter, String chainSpecificFilterConfig) {
+ if (filter instanceof PathConfigProcessor) {
+ ((PathConfigProcessor) filter).processPathConfig(chainName, chainSpecificFilterConfig);
+ } else {
+ String msg = "chainSpecificFilterConfig was specified as a method argument, but the underlying " +
+ "Filter instance is not an 'instanceof' " +
+ PathConfigProcessor.class.getName() + ". This is required if the filter is to accept " +
+ "chain-specific configuration.";
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ protected NamedFilterList ensureChain(String chainName) {
+ NamedFilterList chain = getChain(chainName);
+ if (chain == null) {
+ chain = new SimpleNamedFilterList(chainName);
+ this.filterChains.put(chainName, chain);
+ }
+ return chain;
+ }
+
+ public void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) {
+ Filter filter = getFilter(filterName);
+ if (filter == null) {
+ throw new IllegalArgumentException("There is no filter with name '" + filterName +
+ "' to apply to chain [" + chainName + "]");
+ }
+ if (StringUtils.hasText(chainSpecificFilterConfig)) {
+ applyChainConfig(chainName, filter, chainSpecificFilterConfig);
+ }
+
+ NamedFilterList chain = ensureChain(chainName);
+ chain.add(filter);
+ }
+
+ public NamedFilterList getChain(String chainName) {
+ return this.filterChains.get(chainName);
+ }
+
+ public boolean hasChains() {
+ return !CollectionUtils.isEmpty(this.filterChains);
+ }
+
+ public Set<String> getChainNames() {
+ //noinspection unchecked
+ return this.filterChains != null ? this.filterChains.keySet() : Collections.EMPTY_SET;
+ }
+
+ public FilterChain proxy(FilterChain original, String chainName) {
+ NamedFilterList configured = getChain(chainName);
+ if (configured == null) {
+ String msg = "There is no configured chain under the name/key [" + chainName + "].";
+ throw new IllegalArgumentException(msg);
+ }
+ return configured.proxy(original);
+ }
+
+ /**
+ * Returns the {@code FilterChain} to use for the specified application path, or {@code null} if there
+ * was not a configured chain for the specified path.
+ * <p/>
+ * The default implementation simply calls <code>this.chains.get(chainUrl)</code> to acquire the configured
+ * {@code List<Filter>} filter chain. If that configured chain is non-null and not empty, it is
+ * returned, otherwise {@code null} is returned to indicate that the {@code originalChain} should be
+ * used instead.
+ *
+ * @param chainUrl the configured filter chain url
+ * @param originalChain the original FilterChain given by the Servlet container.
+ * @return the {@code FilterChain} to use for the specified application path, or {@code null} if the
+ * original {@code FilterChain} should be used.
+ */
+ public FilterChain getChain(String chainUrl, FilterChain originalChain) {
+ Map<String, NamedFilterList> filterChains = getFilterChains();
+ List<Filter> pathFilters = filterChains != null ? filterChains.get(chainUrl) : null;
+ if (!CollectionUtils.isEmpty(pathFilters)) {
+ return createChain(pathFilters, originalChain);
+ }
+ return null;
+ }
+
+ /**
+ * Creates a new FilterChain based on the specified configured url filter chain and original chain.
+ * <p/>
+ * The input arguments are expected be be non-null and non-empty, since these conditions are accounted for in the
+ * {@link #getChain(String, javax.servlet.FilterChain) getChain(chainUrl,originalChain)} implementation that
+ * calls this method.
+ * <p/>
+ * The default implementation merely returns
+ * <code>new {@link org.apache.shiro.web.servlet.ProxiedFilterChain FilterChainWrapper(filters, originalChain)}</code>,
+ * and can be overridden by subclasses for custom creation.
+ *
+ * @param filters the configured filter chain for the incoming request application path
+ * @param originalChain the original FilterChain given by the Servlet container.
+ * @return a new FilterChain based on the specified configured url filter chain and original chain.
+ */
+ protected FilterChain createChain(List<Filter> filters, FilterChain originalChain) {
+ return new ProxiedFilterChain(originalChain, filters);
+ }
+
+ /**
+ * Initializes the filter by calling <code>filter.init( {@link #getFilterConfig() getFilterConfig()} );</code>.
+ *
+ * @param filter the filter to initialize with the <code>FilterConfig</code>.
+ */
+ protected void initFilter(Filter filter) {
+ FilterConfig filterConfig = getFilterConfig();
+ if (filterConfig == null) {
+ throw new IllegalStateException("FilterConfig attribute has not been set. This must occur before filter " +
+ "initialization can occur.");
+ }
+ try {
+ filter.init(filterConfig);
+ } catch (ServletException e) {
+ throw new ConfigurationException(e);
+ }
+ }
+
+ protected void createFilters() {
+ addDefaultFilters();
+ }
+
+ protected void addFilterIfNecessary(String name, Filter filter) {
+ if (getFilter(name) == null) {
+ //has not been added yet, so add it now:
+ if (filter instanceof Nameable) {
+ ((Nameable) filter).setName(name);
+ }
+ addFilter(name, filter);
+ }
+ }
+
+ protected void addDefaultFilters() {
+ addFilter("anon", new AnonymousFilter(), true, false);
+ addFilter("user", new UserFilter(), true, false);
+ addFilter("authc", new FormAuthenticationFilter(), true, false);
+ addFilter("authcBasic", new BasicHttpAuthenticationFilter(), true, false);
+ addFilter("roles", new RolesAuthorizationFilter(), true, false);
+ addFilter("perms", new PermissionsAuthorizationFilter(), true, false);
+ addFilter("port", new PortFilter(), true, false);
+ addFilter("ssl", new SslFilter(), true, false);
+ }
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainManager.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainManager.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainManager.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,118 @@
+/*
+ * 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.filter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import java.util.Set;
+
+/**
+ * @since 1.0
+ */
+public interface FilterChainManager {
+
+ /**
+ * Returns the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with
+ * that name.
+ *
+ * @param chainName the name identifying the filter chain.
+ * @return the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with
+ * that name.
+ */
+ NamedFilterList getChain(String chainName);
+
+ /**
+ * Returns {@code true} if one or more configured chains are available, {@code false} if none are configured.
+ *
+ * @return {@code true} if one or more configured chains are available, {@code false} if none are configured.
+ */
+ boolean hasChains();
+
+ /**
+ * Returns the names of all configured chains or an empty {@code Set} if no chains have been configured.
+ *
+ * @return the names of all configured chains or an empty {@code Set} if no chains have been configured.
+ */
+ Set<String> getChainNames();
+
+ /**
+ * Proxies the specified {@code original} FilterChain with the named chain. The returned
+ * {@code FilterChain} instance will first execute the configured named chain and then lastly invoke the given
+ * {@code original} chain.
+ *
+ * @param original the original FilterChain to proxy
+ * @param chainName the name of the internal configured filter chain that should 'sit in front' of the specified
+ * original chain.
+ * @return a {@code FilterChain} instance that will execute the named chain and then finally the
+ * specified {@code original} FilterChain instance.
+ * @throws IllegalArgumentException if there is no configured chain with the given {@code chainName}.
+ */
+ FilterChain proxy(FilterChain original, String chainName);
+
+ /**
+ * Adds a filter to the 'pool' of available filters that can be used when
+ * {@link #addToChain(String, String, String) creating filter chains}.
+ * <p/>
+ * Calling this method is effectively the same as calling
+ * <code>{@link #addFilter(String, javax.servlet.Filter, boolean) addFilter}(name, filter, <b>true</b>);</code>
+ *
+ * @param name the name to assign to the filter, used to reference the filter in chain definitions
+ * @param filter the filter to initialize and then add to the pool of available filters that can be used
+ */
+ void addFilter(String name, Filter filter);
+
+ /**
+ * Adds a filter to the 'pool' of available filters that can be used when
+ * {@link #addToChain(String, String, String) creating filter chains}.
+ *
+ * @param name the name to assign to the filter, used to reference the filter in chain definitions
+ * @param filter the filter to assign to the filter pool
+ * @param init whether or not the {@code Filter} should be
+ * {@link Filter#init(javax.servlet.FilterConfig) initialized} first before being added to the pool.
+ */
+ void addFilter(String name, Filter filter, boolean init);
+
+ /**
+ * Adds (appends) a filter to the filter chain identified by the given {@code chainName}. If there is no chain
+ * with the given name, a new one is created and the filter will be the first in the chain.
+ *
+ * @param chainName the name of the chain where the filter will be appended.
+ * @param filterName the name of the {@link #addFilter registered} filter to add to the chain.
+ * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered}
+ * filter under the given {@code filterName}
+ */
+ void addToChain(String chainName, String filterName);
+
+ /**
+ * Adds (appends) a filter to the filter chain identified by the given {@code chainName}. If there is no chain
+ * with the given name, a new one is created and the filter will be the first in the chain.
+ * <p/>
+ * Note that the final argument expects the associated filter to be an instance of
+ * a {@link org.apache.shiro.web.filter.PathConfigProcessor PathConfigProcessor} to accept per-chain configuration.
+ * If it is not, a {@link IllegalArgumentException} will be thrown.
+ *
+ * @param chainName the name of the chain where the filter will be appended.
+ * @param filterName the name of the {@link #addFilter registered} filter to add to the chain.
+ * @param chainSpecificFilterConfig the filter-specific configuration that should be applied for only the specified
+ * filter chain.
+ * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered}
+ * filter under the given {@code filterName}
+ */
+ void addToChain(String chainName, String filterName, String chainSpecificFilterConfig);
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainResolver.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainResolver.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainResolver.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/FilterChainResolver.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,54 @@
+/*
+ * 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.filter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * A {@code FilterChainResolver} can resolve an appropriate {@link FilterChain} to execute during a
+ * {@code ServletRequest}. It allows resolution of arbitrary filter chains which can be executed for any given
+ * request or URI/URL.
+ * <p/>
+ * This mechanism allows for a much more flexible FilterChain resolution than normal {@code web.xml} servlet filter
+ * definitions: it allows arbitrary filter chains to be defined per URL in a much more concise and easy to read manner,
+ * and even allows filter chains to be dynamically resolved or constructed at runtime if the underlying implementation
+ * supports it.
+ *
+ * @since 1.0
+ */
+public interface FilterChainResolver {
+
+ /**
+ * Returns the filter chain that should be executed for the given request, or <code>null</code> if the
+ * original chain should be used.
+ * <p/>
+ * <p>This method allows a implementation to define arbitrary security {@link javax.servlet.Filter Filter}
+ * chains for any given request or URL pattern.
+ *
+ * @param request the incoming ServletRequest
+ * @param response the outgoing ServletResponse
+ * @param originalChain the original <code>FilterChain</code> intercepted by the ShiroFilter.
+ * @return the filter chain that should be executed for the given request, or <code>null</code> if the
+ * original chain should be used.
+ */
+ FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);
+
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/NamedFilterList.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/NamedFilterList.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/NamedFilterList.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/NamedFilterList.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,33 @@
+/*
+ * 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.filter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import java.util.List;
+
+/**
+ * @since 1.0
+ */
+public interface NamedFilterList extends List<Filter> {
+
+ String getName();
+
+ FilterChain proxy(FilterChain filterChain);
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilterChainResolver.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilterChainResolver.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilterChainResolver.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/PathMatchingFilterChainResolver.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,139 @@
+/*
+ * 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.filter;
+
+import org.apache.shiro.util.AntPathMatcher;
+import org.apache.shiro.util.PatternMatcher;
+import org.apache.shiro.web.WebUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * @since 1.0
+ */
+public class PathMatchingFilterChainResolver implements FilterChainResolver {
+
+ private static transient final Logger log = LoggerFactory.getLogger(PathMatchingFilterChainResolver.class);
+
+ private FilterChainManager filterChainManager;
+
+ protected PatternMatcher pathMatcher;
+
+ public PathMatchingFilterChainResolver() {
+ this.pathMatcher = new AntPathMatcher();
+ }
+
+ public PathMatchingFilterChainResolver(FilterConfig filterConfig) {
+ this();
+ this.filterChainManager = new DefaultFilterChainManager(filterConfig);
+ }
+
+ /**
+ * Returns the {@code PatternMatcher} used when determining if an incoming request's path
+ * matches a configured filter chain. Unless overridden, the
+ * default implementation is an {@link org.apache.shiro.util.AntPathMatcher AntPathMatcher}.
+ *
+ * @return the {@code PatternMatcher} used when determining if an incoming request's path
+ * matches a configured filter chain.
+ */
+ public PatternMatcher getPathMatcher() {
+ return pathMatcher;
+ }
+
+ /**
+ * Sets the {@code PatternMatcher} used when determining if an incoming request's path
+ * matches a configured filter chain. Unless overridden, the
+ * default implementation is an {@link org.apache.shiro.util.AntPathMatcher AntPathMatcher}.
+ *
+ * @param pathMatcher the {@code PatternMatcher} used when determining if an incoming request's path
+ * matches a configured filter chain.
+ */
+ public void setPathMatcher(PatternMatcher pathMatcher) {
+ this.pathMatcher = pathMatcher;
+ }
+
+ public FilterChainManager getFilterChainManager() {
+ return filterChainManager;
+ }
+
+ public void setFilterChainManager(FilterChainManager filterChainManager) {
+ this.filterChainManager = filterChainManager;
+ }
+
+ public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
+ FilterChainManager filterChainManager = getFilterChainManager();
+ if (!filterChainManager.hasChains()) {
+ return null;
+ }
+
+ String requestURI = getPathWithinApplication(request);
+
+ //the 'chain names' in this implementation are actually path patterns defined by the user. We just use them
+ //as the chain name for the FilterChainManager's requirements
+ for (String pathPattern : filterChainManager.getChainNames()) {
+
+ // If the path does match, then pass on to the subclass implementation for specific checks:
+ if (pathMatches(pathPattern, requestURI)) {
+ if (log.isTraceEnabled()) {
+ log.trace("Matched path pattern [" + pathPattern + "] for requestURI [" + requestURI + "]. " +
+ "Utilizing corresponding filter chain...");
+ }
+ return filterChainManager.proxy(originalChain, pathPattern);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns {@code true} if an incoming request's path (the {@code path} argument)
+ * matches a configured filter chain path in the {@code [urls]} section (the {@code pattern} argument),
+ * {@code false} otherwise.
+ * <p/>
+ * Simply delegates to
+ * <b><code>{@link #getPathMatcher() getPathMatcher()}.{@link org.apache.shiro.util.PatternMatcher#matches(String, String) matches(pattern,path)}</code></b>,
+ * but can be overridden by subclasses for custom matching behavior.
+ *
+ * @param pattern the pattern to match against
+ * @param path the value to match with the specified {@code pattern}
+ * @return {@code true} if the request {@code path} matches the specified filter chain url {@code pattern},
+ * {@code false} otherwise.
+ */
+ protected boolean pathMatches(String pattern, String path) {
+ PatternMatcher pathMatcher = getPathMatcher();
+ return pathMatcher.matches(pattern, path);
+ }
+
+ /**
+ * Merely returns
+ * <code>WebUtils.{@link org.apache.shiro.web.WebUtils#getPathWithinApplication(javax.servlet.http.HttpServletRequest) getPathWithinApplication(request)}</code>
+ * and can be overridden by subclasses for custom request-to-application-path resolution behavior.
+ *
+ * @param request the incoming {@code ServletRequest}
+ * @return the request's path within the appliation.
+ */
+ protected String getPathWithinApplication(ServletRequest request) {
+ return WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
+ }
+}
Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/SimpleNamedFilterList.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/SimpleNamedFilterList.java?rev=814073&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/SimpleNamedFilterList.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/filter/SimpleNamedFilterList.java Fri Sep 11 23:00:25 2009
@@ -0,0 +1,148 @@
+/*
+ * 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.filter;
+
+import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.web.servlet.ProxiedFilterChain;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import java.util.*;
+
+/**
+ * @since 1.0
+ */
+public class SimpleNamedFilterList implements NamedFilterList {
+
+ private String name;
+ private List<Filter> backingList;
+
+ public SimpleNamedFilterList(String name) {
+ this.backingList = new ArrayList<Filter>();
+ setName(name);
+ }
+
+ protected void setName(String name) {
+ if (!StringUtils.hasText(name)) {
+ throw new IllegalArgumentException("Cannot specify an empty name.");
+ }
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public FilterChain proxy(FilterChain orig) {
+ return new ProxiedFilterChain(orig, this);
+ }
+
+ public boolean add(Filter filter) {
+ return this.backingList.add(filter);
+ }
+
+ public void add(int index, Filter filter) {
+ this.backingList.add(index, filter);
+ }
+
+ public boolean addAll(Collection<? extends Filter> c) {
+ return this.backingList.addAll(c);
+ }
+
+ public boolean addAll(int index, Collection<? extends Filter> c) {
+ return this.backingList.addAll(index, c);
+ }
+
+ public void clear() {
+ this.backingList.clear();
+ }
+
+ public boolean contains(Object o) {
+ return this.backingList.contains(o);
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ return this.backingList.containsAll(c);
+ }
+
+ public Filter get(int index) {
+ return this.backingList.get(index);
+ }
+
+ public int indexOf(Object o) {
+ return this.backingList.indexOf(o);
+ }
+
+ public boolean isEmpty() {
+ return this.backingList.isEmpty();
+ }
+
+ public Iterator<Filter> iterator() {
+ return this.backingList.iterator();
+ }
+
+ public int lastIndexOf(Object o) {
+ return this.backingList.lastIndexOf(o);
+ }
+
+ public ListIterator<Filter> listIterator() {
+ return this.backingList.listIterator();
+ }
+
+ public ListIterator<Filter> listIterator(int index) {
+ return this.backingList.listIterator(index);
+ }
+
+ public Filter remove(int index) {
+ return this.backingList.remove(index);
+ }
+
+ public boolean remove(Object o) {
+ return this.backingList.remove(o);
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ return this.backingList.removeAll(c);
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ return this.backingList.retainAll(c);
+ }
+
+ public Filter set(int index, Filter filter) {
+ return this.backingList.set(index, filter);
+ }
+
+ public int size() {
+ return this.backingList.size();
+ }
+
+ public List<Filter> subList(int fromIndex, int toIndex) {
+ return this.backingList.subList(fromIndex, toIndex);
+ }
+
+ public Object[] toArray() {
+ return this.backingList.toArray();
+ }
+
+ public <T> T[] toArray(T[] a) {
+ //noinspection SuspiciousToArrayCall
+ return this.backingList.toArray(a);
+ }
+}
Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java?rev=814073&r1=814072&r2=814073&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java Fri Sep 11 23:00:25 2009
@@ -39,6 +39,7 @@
}
protected Subject newSubject(SecurityManager sm, ServletRequest request, ServletResponse response) {
+ ThreadContext.bind(sm);
WebUtils.bind(request);
WebUtils.bind(response);
WebSubject subject = new WebSubject.Builder(sm, request, response).buildWebSubject();