You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by ad...@apache.org on 2010/05/26 20:34:49 UTC

svn commit: r948527 [36/38] - in /incubator/shiro: branches/shiro-root-1.0.x/ branches/shiro-root-1.0.x/all/ branches/shiro-root-1.0.x/core/src/main/java/org/apache/shiro/ branches/shiro-root-1.0.x/core/src/main/java/org/apache/shiro/aop/ branches/shir...

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java Wed May 26 18:34:28 2010
@@ -1,201 +1,201 @@
-/*
- * 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.servlet;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import java.io.IOException;
-
-/**
- * A Servlet Filter that enables AOP-style "around" advice for a ServletRequest via
- * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) preHandle},
- * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) postHandle},
- * and {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
- * hooks.
- *
- * @author Les Hazlewood
- * @since 0.9
- */
-public abstract class AdviceFilter extends OncePerRequestFilter {
-
-    /**
-     * The static logger available to this class only
-     */
-    private static final Logger log = LoggerFactory.getLogger(AdviceFilter.class);
-
-    /**
-     * Returns {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
-     * It is called before the chain is actually consulted/executed.
-     * <p/>
-     * The default implementation returns {@code true} always and exists as a template method for subclasses.
-     *
-     * @param request  the incoming ServletRequest
-     * @param response the outgoing ServletResponse
-     * @return {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
-     * @throws Exception if there is any error.
-     */
-    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
-        return true;
-    }
-
-    /**
-     * Allows 'post' advice logic to be called, but only if no exception occurs during filter chain execution.  That
-     * is, if {@link #executeChain executeChain} throws an exception, this method will never be called.  Be aware of
-     * this when implementing logic.  Most resource 'cleanup' behavior is often done in the
-     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion(request,response,exception)}
-     * implementation, which is guaranteed to be called for every request, even when the chain processing throws
-     * an Exception.
-     * <p/>
-     * The default implementation does nothing (no-op) and exists as a template method for subclasses.
-     *
-     * @param request  the incoming ServletRequest
-     * @param response the outgoing ServletResponse
-     * @throws Exception if an error occurs.
-     */
-    @SuppressWarnings({"UnusedDeclaration"})
-    protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
-    }
-
-    /**
-     * Called in all cases in a {@code finally} block even if {@link #preHandle preHandle} returns
-     * {@code false} or if an exception is thrown during filter chain processing.  Can be used for resource
-     * cleanup if so desired.
-     * <p/>
-     * The default implementation does nothing (no-op) and exists as a template method for subclasses.
-     *
-     * @param request   the incoming ServletRequest
-     * @param response  the outgoing ServletResponse
-     * @param exception any exception thrown during {@link #preHandle preHandle}, {@link #executeChain executeChain},
-     *                  or {@link #postHandle postHandle} execution, or {@code null} if no exception was thrown
-     *                  (i.e. the chain processed successfully).
-     * @throws Exception if an error occurs.
-     */
-    @SuppressWarnings({"UnusedDeclaration"})
-    public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
-    }
-
-    /**
-     * Actually executes the specified filter chain by calling <code>chain.doFilter(request,response);</code>.
-     * <p/>
-     * Can be overridden by subclasses for custom logic.
-     *
-     * @param request  the incoming ServletRequest
-     * @param response the outgoing ServletResponse
-     * @param chain    the filter chain to execute
-     * @throws Exception if there is any error executing the chain.
-     */
-    protected void executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
-        chain.doFilter(request, response);
-    }
-
-    /**
-     * Actually implements the chain execution logic, utilizing
-     * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) pre},
-     * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) post}, and
-     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) after}
-     * advice hooks.
-     *
-     * @param request  the incoming ServletRequest
-     * @param response the outgoing ServletResponse
-     * @param chain    the filter chain to execute
-     * @throws ServletException if a servlet-related error occurs
-     * @throws IOException      if an IO error occurs
-     */
-    public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
-            throws ServletException, IOException {
-
-        Exception exception = null;
-
-        try {
-
-            boolean continueChain = preHandle(request, response);
-            if (log.isTraceEnabled()) {
-                log.trace("Invoked preHandle method.  Continuing chain?: [" + continueChain + "]");
-            }
-
-            if (continueChain) {
-                executeChain(request, response, chain);
-            }
-
-            postHandle(request, response);
-            if (log.isTraceEnabled()) {
-                log.trace("Successfully invoked postHandle method");
-            }
-
-        } catch (Exception e) {
-            exception = e;
-        } finally {
-            cleanup(request, response, exception);
-        }
-    }
-
-    /**
-     * Executes cleanup logic in the {@code finally} code block in the
-     * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) doFilterInternal}
-     * implementation.
-     * <p/>
-     * This implementation specifically calls
-     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
-     * as well as handles any exceptions properly.
-     *
-     * @param request  the incoming {@code ServletRequest}
-     * @param response the outgoing {@code ServletResponse}
-     * @param existing any exception that might have occurred while executing the {@code FilterChain} or
-     *                 pre or post advice, or {@code null} if the pre/chain/post execution did not throw an {@code Exception}.
-     * @throws ServletException if any exception other than an {@code IOException} is thrown.
-     * @throws IOException      if the pre/chain/post execution throw an {@code IOException}
-     */
-    protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
-            throws ServletException, IOException {
-        Exception exception = existing;
-        try {
-            afterCompletion(request, response, exception);
-            if (log.isTraceEnabled()) {
-                log.trace("Successfully invoked afterCompletion method.");
-            }
-        } catch (Exception e) {
-            if (exception == null) {
-                exception = e;
-            } else {
-                log.debug("afterCompletion implementation threw an exception.  This will be ignored to " +
-                        "allow the original source exception to be propagated.", e);
-            }
-        }
-        if (exception != null) {
-            if (exception instanceof ServletException) {
-                throw (ServletException) exception;
-            } else if (exception instanceof IOException) {
-                throw (IOException) exception;
-            } else {
-                if (log.isDebugEnabled()) {
-                    String msg = "Filter execution resulted in an unexpected Exception " +
-                            "(not IOException or ServletException as the Filter API recommends).  " +
-                            "Wrapping in ServletException and propagating.";
-                    log.debug(msg);
-                }
-                throw new ServletException(exception);
-            }
-        }
-    }
-}
+/*
+ * 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.servlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+
+/**
+ * A Servlet Filter that enables AOP-style &quot;around&quot; advice for a ServletRequest via
+ * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) preHandle},
+ * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) postHandle},
+ * and {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
+ * hooks.
+ *
+ * @author Les Hazlewood
+ * @since 0.9
+ */
+public abstract class AdviceFilter extends OncePerRequestFilter {
+
+    /**
+     * The static logger available to this class only
+     */
+    private static final Logger log = LoggerFactory.getLogger(AdviceFilter.class);
+
+    /**
+     * Returns {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
+     * It is called before the chain is actually consulted/executed.
+     * <p/>
+     * The default implementation returns {@code true} always and exists as a template method for subclasses.
+     *
+     * @param request  the incoming ServletRequest
+     * @param response the outgoing ServletResponse
+     * @return {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
+     * @throws Exception if there is any error.
+     */
+    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
+        return true;
+    }
+
+    /**
+     * Allows 'post' advice logic to be called, but only if no exception occurs during filter chain execution.  That
+     * is, if {@link #executeChain executeChain} throws an exception, this method will never be called.  Be aware of
+     * this when implementing logic.  Most resource 'cleanup' behavior is often done in the
+     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion(request,response,exception)}
+     * implementation, which is guaranteed to be called for every request, even when the chain processing throws
+     * an Exception.
+     * <p/>
+     * The default implementation does nothing (no-op) and exists as a template method for subclasses.
+     *
+     * @param request  the incoming ServletRequest
+     * @param response the outgoing ServletResponse
+     * @throws Exception if an error occurs.
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
+    }
+
+    /**
+     * Called in all cases in a {@code finally} block even if {@link #preHandle preHandle} returns
+     * {@code false} or if an exception is thrown during filter chain processing.  Can be used for resource
+     * cleanup if so desired.
+     * <p/>
+     * The default implementation does nothing (no-op) and exists as a template method for subclasses.
+     *
+     * @param request   the incoming ServletRequest
+     * @param response  the outgoing ServletResponse
+     * @param exception any exception thrown during {@link #preHandle preHandle}, {@link #executeChain executeChain},
+     *                  or {@link #postHandle postHandle} execution, or {@code null} if no exception was thrown
+     *                  (i.e. the chain processed successfully).
+     * @throws Exception if an error occurs.
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
+    }
+
+    /**
+     * Actually executes the specified filter chain by calling <code>chain.doFilter(request,response);</code>.
+     * <p/>
+     * Can be overridden by subclasses for custom logic.
+     *
+     * @param request  the incoming ServletRequest
+     * @param response the outgoing ServletResponse
+     * @param chain    the filter chain to execute
+     * @throws Exception if there is any error executing the chain.
+     */
+    protected void executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
+        chain.doFilter(request, response);
+    }
+
+    /**
+     * Actually implements the chain execution logic, utilizing
+     * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) pre},
+     * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) post}, and
+     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) after}
+     * advice hooks.
+     *
+     * @param request  the incoming ServletRequest
+     * @param response the outgoing ServletResponse
+     * @param chain    the filter chain to execute
+     * @throws ServletException if a servlet-related error occurs
+     * @throws IOException      if an IO error occurs
+     */
+    public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws ServletException, IOException {
+
+        Exception exception = null;
+
+        try {
+
+            boolean continueChain = preHandle(request, response);
+            if (log.isTraceEnabled()) {
+                log.trace("Invoked preHandle method.  Continuing chain?: [" + continueChain + "]");
+            }
+
+            if (continueChain) {
+                executeChain(request, response, chain);
+            }
+
+            postHandle(request, response);
+            if (log.isTraceEnabled()) {
+                log.trace("Successfully invoked postHandle method");
+            }
+
+        } catch (Exception e) {
+            exception = e;
+        } finally {
+            cleanup(request, response, exception);
+        }
+    }
+
+    /**
+     * Executes cleanup logic in the {@code finally} code block in the
+     * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) doFilterInternal}
+     * implementation.
+     * <p/>
+     * This implementation specifically calls
+     * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
+     * as well as handles any exceptions properly.
+     *
+     * @param request  the incoming {@code ServletRequest}
+     * @param response the outgoing {@code ServletResponse}
+     * @param existing any exception that might have occurred while executing the {@code FilterChain} or
+     *                 pre or post advice, or {@code null} if the pre/chain/post execution did not throw an {@code Exception}.
+     * @throws ServletException if any exception other than an {@code IOException} is thrown.
+     * @throws IOException      if the pre/chain/post execution throw an {@code IOException}
+     */
+    protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
+            throws ServletException, IOException {
+        Exception exception = existing;
+        try {
+            afterCompletion(request, response, exception);
+            if (log.isTraceEnabled()) {
+                log.trace("Successfully invoked afterCompletion method.");
+            }
+        } catch (Exception e) {
+            if (exception == null) {
+                exception = e;
+            } else {
+                log.debug("afterCompletion implementation threw an exception.  This will be ignored to " +
+                        "allow the original source exception to be propagated.", e);
+            }
+        }
+        if (exception != null) {
+            if (exception instanceof ServletException) {
+                throw (ServletException) exception;
+            } else if (exception instanceof IOException) {
+                throw (IOException) exception;
+            } else {
+                if (log.isDebugEnabled()) {
+                    String msg = "Filter execution resulted in an unexpected Exception " +
+                            "(not IOException or ServletException as the Filter API recommends).  " +
+                            "Wrapping in ServletException and propagating.";
+                    log.debug(msg);
+                }
+                throw new ServletException(exception);
+            }
+        }
+    }
+}

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java
------------------------------------------------------------------------------
    svn:esvn = ps

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/Cookie.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=948527&r1=948526&r2=948527&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 Wed May 26 18:34:28 2010
@@ -1,397 +1,397 @@
-/*
- * 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.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.CollectionUtils;
-import org.apache.shiro.web.config.IniFilterChainResolverFactory;
-import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
-import org.apache.shiro.web.filter.mgt.FilterChainResolver;
-import org.apache.shiro.web.mgt.WebSecurityManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Map;
-
-/**
- * Main Servlet Filter that configures and enables all Shiro functions within a web application by using the
- * <a href="http://en.wikipedia.org/wiki/INI_file">INI</a> configuration format.
- * <p/>
- * The following is a fully commented example that documents how to configure it:
- * <pre>&lt;filter&gt;
- * &lt;filter-name&gt;ShiroFilter&lt;/filter-name&gt;
- * &lt;filter-class&gt;org.apache.shiro.web.servlet.IniShiroFilter&lt;/filter-class&gt;
- * &lt;init-param&gt;&lt;param-name&gt;config&lt;/param-name&gt;&lt;param-value&gt;
- * #
- * #NOTE:  This config looks pretty long - but its not - its only a few lines of actual config.
- * #       Everything else is just heavily commented to explain things in-depth. Feel free to delete any
- * #       comments that you don't want to read from your own configuration ;)
- * #
- * # Any commented values below that _don't_ start with 'example.pkg' are Shiro's defaults.  If you want to change any
- * # values on those lines, you only need to uncomment the lines you want to change.
- * #
- * [main]
- * # The 'main' section defines Shiro-wide configuration.
- * #
- * # Each section's configuration is essentially an object graph definition in a .properties style (name/value pair)
- * # format.  The beans defined would be those that are used to construct the application's SecurityManager.  It is
- * # essentially 'poor man's' dependency injection via a .properties format.
- * #
- * # --- Defining Realms ---
- * #
- * # Any Realm defined here will automatically be injected into Shiro's default SecurityManager created at start up.
- * # For example:
- * #
- * # myRealm = example.pkg.security.MyRealm
- * #
- * # This would instantiate the some.pkg.security.MyRealm class with a default no-arg constructor and inject it into
- * # the SecurityManager.  More than one realm can be defined if needed.  You can create graphs and reference
- * # other beans ('$' bean reference notation) while defining Realms and other objects:
- * #
- * # <b>connectionFactory</b> = example.pkg.ConnectionFactory
- * # connectionFactory.driverClassName = a.jdbc.Driver
- * # connectionFactory.username = aUsername
- * # connectionFactory.password = aPassword
- * # connectionFactory.minConnections = 3
- * # connectionFactory.maxConnections = 10
- * # ... etc...
- * #
- * # myJdbcRealm = example.pkg.jdbc.MyJdbcRealm
- * # myJdbcRealm.connectionFactory = <b>$connectionFactory</b>
- * # ... etc ...
- * #
- * # --- Realm Factories ---
- * #
- * # If the INI style isn't robust enough for your needs, you also have the option of implementing the
- * # {@link org.apache.shiro.realm.RealmFactory org.apache.shiro.realm.RealmFactory} interface with more complex construction
- * # logic.  Then you can declare the implementation here instead.  The realms it returns will be injected in to the
- * # SecurityManager just as the individual Realms are.  For example:
- * #
- * # aRealmFactory = some.pkg.ClassThatImplementsRealmFactory
- * #
- * # --- SessionManager properties ---
- * #
- * # Except for Realms and RealmFactories, all other objects should be defined and set on the SecurityManager directly.
- * # The default 'securityManager' bean is an instance of {@link org.apache.shiro.web.mgt.DefaultWebSecurityManager}, so you
- * # can set any of its corresponding properties as necessary:
- * #
- * # someObject = some.fully.qualified.ClassName
- * # someObject.propertyN = foo
- * # ...
- * # securityManager.someObject = $someObject
- * #
- * # For example, if you wanted to change Shiro's default session mechanism, you can change the 'sessionMode' property.
- * # By default, Shiro's Session infrastructure in a web environment will use the
- * # Servlet container's HttpSession.  However, if you need to share session state across client types
- * # (e.g. Web MVC plus Java Web Start or Flash), or are doing distributed/shared Sessions for
- * # Single Sign On, HttpSessions aren't good enough.  You'll need to use Shiro's more powerful
- * # (and client-agnostic) session management.  You can enable this by uncommenting the following line
- * # and changing 'http' to 'native'
- * #
- * #securityManager.{@link org.apache.shiro.web.mgt.DefaultWebSecurityManager#setSessionMode(String) sessionMode} = http
- * #
- * [filters]
- * # This section defines the 'pool' of all Filters available to the url path definitions in the [urls] section below.
- * #
- * # The following commented values are already provided by Shiro by default and are immediately usable
- * # in the [urls] definitions below.  If you like, you may override any values by uncommenting only the lines
- * # you need to change.
- * #
- * # Each Filter is configured based on its functionality and/or protocol.  You should read each
- * # Filter's JavaDoc to fully understand what each does and how it works as well as how it would
- * # affect the user experience.
- * #
- * # Form-based Authentication filter:
- * #<a name="authc"></a>authc = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter}
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setLoginUrl(String) loginUrl} = /login.jsp
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setUsernameParam(String) usernameParam} = username
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setPasswordParam(String) passwordParam} = password
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setRememberMeParam(String) rememberMeParam} = rememberMe
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setSuccessUrl(String) successUrl}  = /login.jsp
- * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setFailureKeyAttribute(String) failureKeyAttribute} = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#DEFAULT_ERROR_KEY_ATTRIBUTE_NAME}
- * #
- * # Http BASIC Authentication filter:
- * #<a name="authcBasic"></a>authcBasic = {@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter}
- * #authcBasic.{@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter#setApplicationName(String) applicationName} = application
- * #
- * # Roles filter: requires the requesting user to have one or more roles for the request to continue.
- * # If they do not have the specified roles, they are redirected to the specified URL.
- * #<a name="roles"></a>roles = {@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter}
- * #roles.{@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
- * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
- * # of redirecting to a page.  If you want to show a 'nice page' instead, you should specify that url.
- * #
- * # Permissions filter: requires the requesting user to have one or more permissions for the request to
- * # continue, and if they do not, redirects them to the specified URL.
- * #<a name="perms"></a>perms = {@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter}
- * #perms.{@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
- * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
- * # of redirecting to a page.  If you want to show a 'nice page' instead, you should specify that url.  Many
- * # applications like to use the same url specified in roles.unauthorizedUrl above.
- * #
- * #
- * # Define your own filters here as you would any other object as described in the '[main]' section above (properties,
- * # $references, etc).  To properly handle url path matching (see the [urls] section below), your
- * # filter should extend the {@link org.apache.shiro.web.filter.PathMatchingFilter PathMatchingFilter} abstract class.
- * #
- * [urls]
- * # This section defines url path mappings.  Each mapping entry must be on a single line and conform to the
- * # following representation:
- * #
- * # ant_path_expression = path_specific_filter_chain_definition
- * #
- * # For any request that matches a specified path, the corresponding value defines a comma-delimited chain of
- * # filters to execute for that request.
- * #
- * # This is incredibly powerful in that you can define arbitrary filter chains for any given request pattern
- * # to greatly customize the security experience.
- * #
- * # The path_specific_filter_chain_definition must match the following format:
- * #
- * # filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]
- * #
- * # where 'filterN' is the name of an filter defined above in the [filters] section and
- * # '[optional_configN]' is an optional bracketed string that has meaning for that particular filter for
- * # _that particular path_.  If the filter does not need specific config for that url path, you may
- * # discard the brackets so filterN[] just becomes filterN.
- * #
- * # And because filter tokens define chains, order matters!  Define the tokens for each path pattern
- * # in the order you want them to filter (comma-delimited).
- * #
- * # Finally, each filter is free to handle the response however it wants if its necessary
- * # conditions are not met (redirect, HTTP error code, direct rendering, etc).  Otherwise, it is expected to allow
- * # the request to continue through the chain on to the final destination view.
- * #
- * # Examples:
- * #
- * # To illustrate chain configuration, look at the /account/** mapping below.  This says
- * # &quot;apply the above 'authcBasic' filter to any request matching the '/account/**' pattern&quot;.  Since the
- * # 'authcBasic' filter does not need any path-specific config, it doesn't have any config brackets [].
- * #
- * # The /remoting/** definition on the other hand uses the 'roles' and 'perms' filters which do use
- * # bracket notation.  That definition says:
- * #
- * # &quot;To access /remoting/** urls, ensure that the user is first authenticated ('authcBasic'), then ensure that user
- * # has the 'b2bClient' role, and then finally ensure that they have the 'remote:invoke:lan,wan' permission.&quot;
- * #
- * # (Note that because elements within brackets [ ] are comma-delimited themselves, we needed to quote any config
- * # value which may require a comma. If we didn't do that, the permission filter below would interpret
- * # the text between the brackets as two permissions: 'remote:invoke:lan' and 'wan' instead of the
- * # single desired 'remote:invoke:lan,wan' token.  So, you can use quotes wherever you need to escape internal
- * # commas.)
- * #
- * /account/** = <a href="#authcBasic">authcBasic</a>
- * /remoting/** = <a href="#authcBasic">authcBasic</a>, <a href="#roles">roles</a>[b2bClient], <a href="#perms">perms</a>["remote:invoke:lan,wan"]
- * &lt;/param-value&gt;&lt;/init-param&gt;
- * &lt;/filter&gt;
- * <p/>
- * &lt;filter-mapping&gt;
- *     &lt;filter-name&gt;ShiroFilter&lt;/filter-name&gt;
- *     &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
- * &lt;/filter-mapping&gt;</pre>
- *
- * @since 1.0
- */
-public class IniShiroFilter extends AbstractShiroFilter {
-
-    public static final String CONFIG_INIT_PARAM_NAME = "config";
-    public static final String CONFIG_PATH_INIT_PARAM_NAME = "configPath";
-
-    private static final Logger log = LoggerFactory.getLogger(IniShiroFilter.class);
-
-    private String config;
-    private String configPath;
-
-    public IniShiroFilter() {
-    }
-
-    /**
-     * Returns the actual INI configuration text to use to build the {@link SecurityManager} and
-     * {@link FilterChainResolver} used by the web application or {@code null} if the
-     * {@link #getConfigPath() configPath} should be used to load a fallback INI source.
-     * <p/>
-     * This value is {@code null} by default, but it will be automatically set to the value of the
-     * '{@code config}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
-     * container at startup.
-     *
-     * @return the actual INI configuration text to use to build the {@link SecurityManager} and
-     *         {@link FilterChainResolver} used by the web application or {@code null} if the
-     *         {@link #getConfigPath() configPath} should be used to load a fallback INI source.
-     */
-    public String getConfig() {
-        return this.config;
-    }
-
-    /**
-     * Sets the actual INI configuration text to use to build the {@link SecurityManager} and
-     * {@link FilterChainResolver} used by the web application.  If this value is {@code null}, the
-     * {@link #getConfigPath() configPath} will be checked to see if a .ini file should be loaded instead.
-     * <p/>
-     * This value is {@code null} by default, but it will be automatically set to the value of the
-     * '{@code config}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
-     * container at startup.
-     *
-     * @param config the actual INI configuration text to use to build the {@link SecurityManager} and
-     *               {@link FilterChainResolver} used by the web application.
-     */
-    public void setConfig(String config) {
-        this.config = config;
-    }
-
-    /**
-     * Returns the config path to be used to load a .ini file for configuration if a configuration is
-     * not specified via the {@link #getConfig() config} attribute.
-     * <p/>
-     * This value is {@code null} by default, but it will be automatically set to the value of the
-     * '{@code configPath}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
-     * container at startup.
-     *
-     * @return the config path to be used to load a .ini file for configuration if a configuration is
-     *         not specified via the {@link #getConfig() config} attribute.
-     */
-    public String getConfigPath() {
-        return configPath;
-    }
-
-    /**
-     * Sets the config path to be used to load a .ini file for configuration if a configuration is
-     * not specified via the {@link #getConfig() config} attribute.
-     * <p/>
-     * This value is {@code null} by default, but it will be automatically set to the value of the
-     * '{@code configPath}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
-     * container at startup.
-     *
-     * @param configPath the config path to be used to load a .ini file for configuration if a configuration is
-     *                   not specified via the {@link #getConfig() config} attribute.
-     */
-    public void setConfigPath(String configPath) {
-        this.configPath = configPath;
-    }
-
-    public void init() throws Exception {
-        applyInitParams();
-        configure();
-    }
-
-    protected void applyInitParams() throws Exception {
-        String config = getInitParam(CONFIG_INIT_PARAM_NAME);
-        if (config != null) {
-            setConfig(config);
-        }
-        String configPath = getInitParam(CONFIG_PATH_INIT_PARAM_NAME);
-        if (configPath != null) {
-            setConfigPath(configPath);
-        }
-    }
-
-    protected void configure() throws Exception {
-        Ini ini = loadIniFromConfig();
-
-        if (CollectionUtils.isEmpty(ini)) {
-            log.info("Null or empty configuration specified via 'config' init-param.  " +
-                    "Checking path-based configuration.");
-            ini = loadIniFromPath();
-        }
-        if (CollectionUtils.isEmpty(ini)) {
-            log.info("Null or empty configuration specified via '" + CONFIG_INIT_PARAM_NAME + "' or '" +
-                    CONFIG_PATH_INIT_PARAM_NAME + "' filter parameters.  Trying the default " +
-                    IniFactorySupport.DEFAULT_INI_RESOURCE_PATH + " file.");
-            ini = IniFactorySupport.loadDefaultClassPathIni();
-        }
-
-        Map<String, ?> objects = applySecurityManager(ini);
-        applyFilterChainResolver(ini, objects);
-    }
-
-    protected Ini loadIniFromConfig() {
-        Ini ini = null;
-        String config = getConfig();
-        if (config != null) {
-            ini = convertConfigToIni(config);
-        }
-        return ini;
-    }
-
-    protected Ini loadIniFromPath() {
-        Ini ini = null;
-        String path = getConfigPath();
-        if (path != null) {
-            ini = convertPathToIni(path);
-        }
-        return ini;
-    }
-
-    protected Map<String, ?> applySecurityManager(Ini ini) {
-        WebIniSecurityManagerFactory factory;
-        if (CollectionUtils.isEmpty(ini)) {
-            factory = new WebIniSecurityManagerFactory();
-        } 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();
-        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);
-
-        return factory.getBeans();
-    }
-
-    protected void applyFilterChainResolver(Ini ini, Map<String, ?> defaults) {
-        if (ini == null || ini.isEmpty()) {
-            //nothing to use to create the resolver, just return
-            //(the AbstractShiroFilter allows a null resolver, in which case the original FilterChain is
-            // always used).
-            return;
-        }
-
-        //only create a resolver if the 'filters' or 'urls' sections are defined:
-        Ini.Section urls = ini.getSection(IniFilterChainResolverFactory.URLS);
-        Ini.Section filters = ini.getSection(IniFilterChainResolverFactory.FILTERS);
-        if ((urls != null && !urls.isEmpty()) || (filters != null && !filters.isEmpty())) {
-            //either the urls section or the filters section was defined.  Go ahead and create the resolver
-            //and set it:
-            IniFilterChainResolverFactory filterChainResolverFactory = new IniFilterChainResolverFactory(ini, defaults);
-            filterChainResolverFactory.setFilterConfig(getFilterConfig());
-            FilterChainResolver resolver = filterChainResolverFactory.getInstance();
-            setFilterChainResolver(resolver);
-        }
-    }
-
-    protected Ini convertConfigToIni(String config) {
-        Ini ini = new Ini();
-        ini.load(config);
-        return ini;
-    }
-
-    protected Ini convertPathToIni(String path) {
-        Ini ini = new Ini();
-        ini.loadFromPath(path);
-        return ini;
-    }
-}
+/*
+ * 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.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.CollectionUtils;
+import org.apache.shiro.web.config.IniFilterChainResolverFactory;
+import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * Main Servlet Filter that configures and enables all Shiro functions within a web application by using the
+ * <a href="http://en.wikipedia.org/wiki/INI_file">INI</a> configuration format.
+ * <p/>
+ * The following is a fully commented example that documents how to configure it:
+ * <pre>&lt;filter&gt;
+ * &lt;filter-name&gt;ShiroFilter&lt;/filter-name&gt;
+ * &lt;filter-class&gt;org.apache.shiro.web.servlet.IniShiroFilter&lt;/filter-class&gt;
+ * &lt;init-param&gt;&lt;param-name&gt;config&lt;/param-name&gt;&lt;param-value&gt;
+ * #
+ * #NOTE:  This config looks pretty long - but its not - its only a few lines of actual config.
+ * #       Everything else is just heavily commented to explain things in-depth. Feel free to delete any
+ * #       comments that you don't want to read from your own configuration ;)
+ * #
+ * # Any commented values below that _don't_ start with 'example.pkg' are Shiro's defaults.  If you want to change any
+ * # values on those lines, you only need to uncomment the lines you want to change.
+ * #
+ * [main]
+ * # The 'main' section defines Shiro-wide configuration.
+ * #
+ * # Each section's configuration is essentially an object graph definition in a .properties style (name/value pair)
+ * # format.  The beans defined would be those that are used to construct the application's SecurityManager.  It is
+ * # essentially 'poor man's' dependency injection via a .properties format.
+ * #
+ * # --- Defining Realms ---
+ * #
+ * # Any Realm defined here will automatically be injected into Shiro's default SecurityManager created at start up.
+ * # For example:
+ * #
+ * # myRealm = example.pkg.security.MyRealm
+ * #
+ * # This would instantiate the some.pkg.security.MyRealm class with a default no-arg constructor and inject it into
+ * # the SecurityManager.  More than one realm can be defined if needed.  You can create graphs and reference
+ * # other beans ('$' bean reference notation) while defining Realms and other objects:
+ * #
+ * # <b>connectionFactory</b> = example.pkg.ConnectionFactory
+ * # connectionFactory.driverClassName = a.jdbc.Driver
+ * # connectionFactory.username = aUsername
+ * # connectionFactory.password = aPassword
+ * # connectionFactory.minConnections = 3
+ * # connectionFactory.maxConnections = 10
+ * # ... etc...
+ * #
+ * # myJdbcRealm = example.pkg.jdbc.MyJdbcRealm
+ * # myJdbcRealm.connectionFactory = <b>$connectionFactory</b>
+ * # ... etc ...
+ * #
+ * # --- Realm Factories ---
+ * #
+ * # If the INI style isn't robust enough for your needs, you also have the option of implementing the
+ * # {@link org.apache.shiro.realm.RealmFactory org.apache.shiro.realm.RealmFactory} interface with more complex construction
+ * # logic.  Then you can declare the implementation here instead.  The realms it returns will be injected in to the
+ * # SecurityManager just as the individual Realms are.  For example:
+ * #
+ * # aRealmFactory = some.pkg.ClassThatImplementsRealmFactory
+ * #
+ * # --- SessionManager properties ---
+ * #
+ * # Except for Realms and RealmFactories, all other objects should be defined and set on the SecurityManager directly.
+ * # The default 'securityManager' bean is an instance of {@link org.apache.shiro.web.mgt.DefaultWebSecurityManager}, so you
+ * # can set any of its corresponding properties as necessary:
+ * #
+ * # someObject = some.fully.qualified.ClassName
+ * # someObject.propertyN = foo
+ * # ...
+ * # securityManager.someObject = $someObject
+ * #
+ * # For example, if you wanted to change Shiro's default session mechanism, you can change the 'sessionMode' property.
+ * # By default, Shiro's Session infrastructure in a web environment will use the
+ * # Servlet container's HttpSession.  However, if you need to share session state across client types
+ * # (e.g. Web MVC plus Java Web Start or Flash), or are doing distributed/shared Sessions for
+ * # Single Sign On, HttpSessions aren't good enough.  You'll need to use Shiro's more powerful
+ * # (and client-agnostic) session management.  You can enable this by uncommenting the following line
+ * # and changing 'http' to 'native'
+ * #
+ * #securityManager.{@link org.apache.shiro.web.mgt.DefaultWebSecurityManager#setSessionMode(String) sessionMode} = http
+ * #
+ * [filters]
+ * # This section defines the 'pool' of all Filters available to the url path definitions in the [urls] section below.
+ * #
+ * # The following commented values are already provided by Shiro by default and are immediately usable
+ * # in the [urls] definitions below.  If you like, you may override any values by uncommenting only the lines
+ * # you need to change.
+ * #
+ * # Each Filter is configured based on its functionality and/or protocol.  You should read each
+ * # Filter's JavaDoc to fully understand what each does and how it works as well as how it would
+ * # affect the user experience.
+ * #
+ * # Form-based Authentication filter:
+ * #<a name="authc"></a>authc = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter}
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setLoginUrl(String) loginUrl} = /login.jsp
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setUsernameParam(String) usernameParam} = username
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setPasswordParam(String) passwordParam} = password
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setRememberMeParam(String) rememberMeParam} = rememberMe
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setSuccessUrl(String) successUrl}  = /login.jsp
+ * #authc.{@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#setFailureKeyAttribute(String) failureKeyAttribute} = {@link org.apache.shiro.web.filter.authc.FormAuthenticationFilter#DEFAULT_ERROR_KEY_ATTRIBUTE_NAME}
+ * #
+ * # Http BASIC Authentication filter:
+ * #<a name="authcBasic"></a>authcBasic = {@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter}
+ * #authcBasic.{@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter#setApplicationName(String) applicationName} = application
+ * #
+ * # Roles filter: requires the requesting user to have one or more roles for the request to continue.
+ * # If they do not have the specified roles, they are redirected to the specified URL.
+ * #<a name="roles"></a>roles = {@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter}
+ * #roles.{@link org.apache.shiro.web.filter.authz.RolesAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
+ * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
+ * # of redirecting to a page.  If you want to show a 'nice page' instead, you should specify that url.
+ * #
+ * # Permissions filter: requires the requesting user to have one or more permissions for the request to
+ * # continue, and if they do not, redirects them to the specified URL.
+ * #<a name="perms"></a>perms = {@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter}
+ * #perms.{@link org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter#setUnauthorizedUrl(String) unauthorizedUrl} =
+ * # (note the above url is null by default, which will cause an HTTP 403 (Access Denied) response instead
+ * # of redirecting to a page.  If you want to show a 'nice page' instead, you should specify that url.  Many
+ * # applications like to use the same url specified in roles.unauthorizedUrl above.
+ * #
+ * #
+ * # Define your own filters here as you would any other object as described in the '[main]' section above (properties,
+ * # $references, etc).  To properly handle url path matching (see the [urls] section below), your
+ * # filter should extend the {@link org.apache.shiro.web.filter.PathMatchingFilter PathMatchingFilter} abstract class.
+ * #
+ * [urls]
+ * # This section defines url path mappings.  Each mapping entry must be on a single line and conform to the
+ * # following representation:
+ * #
+ * # ant_path_expression = path_specific_filter_chain_definition
+ * #
+ * # For any request that matches a specified path, the corresponding value defines a comma-delimited chain of
+ * # filters to execute for that request.
+ * #
+ * # This is incredibly powerful in that you can define arbitrary filter chains for any given request pattern
+ * # to greatly customize the security experience.
+ * #
+ * # The path_specific_filter_chain_definition must match the following format:
+ * #
+ * # filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]
+ * #
+ * # where 'filterN' is the name of an filter defined above in the [filters] section and
+ * # '[optional_configN]' is an optional bracketed string that has meaning for that particular filter for
+ * # _that particular path_.  If the filter does not need specific config for that url path, you may
+ * # discard the brackets so filterN[] just becomes filterN.
+ * #
+ * # And because filter tokens define chains, order matters!  Define the tokens for each path pattern
+ * # in the order you want them to filter (comma-delimited).
+ * #
+ * # Finally, each filter is free to handle the response however it wants if its necessary
+ * # conditions are not met (redirect, HTTP error code, direct rendering, etc).  Otherwise, it is expected to allow
+ * # the request to continue through the chain on to the final destination view.
+ * #
+ * # Examples:
+ * #
+ * # To illustrate chain configuration, look at the /account/** mapping below.  This says
+ * # &quot;apply the above 'authcBasic' filter to any request matching the '/account/**' pattern&quot;.  Since the
+ * # 'authcBasic' filter does not need any path-specific config, it doesn't have any config brackets [].
+ * #
+ * # The /remoting/** definition on the other hand uses the 'roles' and 'perms' filters which do use
+ * # bracket notation.  That definition says:
+ * #
+ * # &quot;To access /remoting/** urls, ensure that the user is first authenticated ('authcBasic'), then ensure that user
+ * # has the 'b2bClient' role, and then finally ensure that they have the 'remote:invoke:lan,wan' permission.&quot;
+ * #
+ * # (Note that because elements within brackets [ ] are comma-delimited themselves, we needed to quote any config
+ * # value which may require a comma. If we didn't do that, the permission filter below would interpret
+ * # the text between the brackets as two permissions: 'remote:invoke:lan' and 'wan' instead of the
+ * # single desired 'remote:invoke:lan,wan' token.  So, you can use quotes wherever you need to escape internal
+ * # commas.)
+ * #
+ * /account/** = <a href="#authcBasic">authcBasic</a>
+ * /remoting/** = <a href="#authcBasic">authcBasic</a>, <a href="#roles">roles</a>[b2bClient], <a href="#perms">perms</a>["remote:invoke:lan,wan"]
+ * &lt;/param-value&gt;&lt;/init-param&gt;
+ * &lt;/filter&gt;
+ * <p/>
+ * &lt;filter-mapping&gt;
+ *     &lt;filter-name&gt;ShiroFilter&lt;/filter-name&gt;
+ *     &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+ * &lt;/filter-mapping&gt;</pre>
+ *
+ * @since 1.0
+ */
+public class IniShiroFilter extends AbstractShiroFilter {
+
+    public static final String CONFIG_INIT_PARAM_NAME = "config";
+    public static final String CONFIG_PATH_INIT_PARAM_NAME = "configPath";
+
+    private static final Logger log = LoggerFactory.getLogger(IniShiroFilter.class);
+
+    private String config;
+    private String configPath;
+
+    public IniShiroFilter() {
+    }
+
+    /**
+     * Returns the actual INI configuration text to use to build the {@link SecurityManager} and
+     * {@link FilterChainResolver} used by the web application or {@code null} if the
+     * {@link #getConfigPath() configPath} should be used to load a fallback INI source.
+     * <p/>
+     * This value is {@code null} by default, but it will be automatically set to the value of the
+     * '{@code config}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
+     * container at startup.
+     *
+     * @return the actual INI configuration text to use to build the {@link SecurityManager} and
+     *         {@link FilterChainResolver} used by the web application or {@code null} if the
+     *         {@link #getConfigPath() configPath} should be used to load a fallback INI source.
+     */
+    public String getConfig() {
+        return this.config;
+    }
+
+    /**
+     * Sets the actual INI configuration text to use to build the {@link SecurityManager} and
+     * {@link FilterChainResolver} used by the web application.  If this value is {@code null}, the
+     * {@link #getConfigPath() configPath} will be checked to see if a .ini file should be loaded instead.
+     * <p/>
+     * This value is {@code null} by default, but it will be automatically set to the value of the
+     * '{@code config}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
+     * container at startup.
+     *
+     * @param config the actual INI configuration text to use to build the {@link SecurityManager} and
+     *               {@link FilterChainResolver} used by the web application.
+     */
+    public void setConfig(String config) {
+        this.config = config;
+    }
+
+    /**
+     * Returns the config path to be used to load a .ini file for configuration if a configuration is
+     * not specified via the {@link #getConfig() config} attribute.
+     * <p/>
+     * This value is {@code null} by default, but it will be automatically set to the value of the
+     * '{@code configPath}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
+     * container at startup.
+     *
+     * @return the config path to be used to load a .ini file for configuration if a configuration is
+     *         not specified via the {@link #getConfig() config} attribute.
+     */
+    public String getConfigPath() {
+        return configPath;
+    }
+
+    /**
+     * Sets the config path to be used to load a .ini file for configuration if a configuration is
+     * not specified via the {@link #getConfig() config} attribute.
+     * <p/>
+     * This value is {@code null} by default, but it will be automatically set to the value of the
+     * '{@code configPath}' {@code init-param} if it exists in the {@code FilterConfig} provided by the servlet
+     * container at startup.
+     *
+     * @param configPath the config path to be used to load a .ini file for configuration if a configuration is
+     *                   not specified via the {@link #getConfig() config} attribute.
+     */
+    public void setConfigPath(String configPath) {
+        this.configPath = configPath;
+    }
+
+    public void init() throws Exception {
+        applyInitParams();
+        configure();
+    }
+
+    protected void applyInitParams() throws Exception {
+        String config = getInitParam(CONFIG_INIT_PARAM_NAME);
+        if (config != null) {
+            setConfig(config);
+        }
+        String configPath = getInitParam(CONFIG_PATH_INIT_PARAM_NAME);
+        if (configPath != null) {
+            setConfigPath(configPath);
+        }
+    }
+
+    protected void configure() throws Exception {
+        Ini ini = loadIniFromConfig();
+
+        if (CollectionUtils.isEmpty(ini)) {
+            log.info("Null or empty configuration specified via 'config' init-param.  " +
+                    "Checking path-based configuration.");
+            ini = loadIniFromPath();
+        }
+        if (CollectionUtils.isEmpty(ini)) {
+            log.info("Null or empty configuration specified via '" + CONFIG_INIT_PARAM_NAME + "' or '" +
+                    CONFIG_PATH_INIT_PARAM_NAME + "' filter parameters.  Trying the default " +
+                    IniFactorySupport.DEFAULT_INI_RESOURCE_PATH + " file.");
+            ini = IniFactorySupport.loadDefaultClassPathIni();
+        }
+
+        Map<String, ?> objects = applySecurityManager(ini);
+        applyFilterChainResolver(ini, objects);
+    }
+
+    protected Ini loadIniFromConfig() {
+        Ini ini = null;
+        String config = getConfig();
+        if (config != null) {
+            ini = convertConfigToIni(config);
+        }
+        return ini;
+    }
+
+    protected Ini loadIniFromPath() {
+        Ini ini = null;
+        String path = getConfigPath();
+        if (path != null) {
+            ini = convertPathToIni(path);
+        }
+        return ini;
+    }
+
+    protected Map<String, ?> applySecurityManager(Ini ini) {
+        WebIniSecurityManagerFactory factory;
+        if (CollectionUtils.isEmpty(ini)) {
+            factory = new WebIniSecurityManagerFactory();
+        } 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();
+        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);
+
+        return factory.getBeans();
+    }
+
+    protected void applyFilterChainResolver(Ini ini, Map<String, ?> defaults) {
+        if (ini == null || ini.isEmpty()) {
+            //nothing to use to create the resolver, just return
+            //(the AbstractShiroFilter allows a null resolver, in which case the original FilterChain is
+            // always used).
+            return;
+        }
+
+        //only create a resolver if the 'filters' or 'urls' sections are defined:
+        Ini.Section urls = ini.getSection(IniFilterChainResolverFactory.URLS);
+        Ini.Section filters = ini.getSection(IniFilterChainResolverFactory.FILTERS);
+        if ((urls != null && !urls.isEmpty()) || (filters != null && !filters.isEmpty())) {
+            //either the urls section or the filters section was defined.  Go ahead and create the resolver
+            //and set it:
+            IniFilterChainResolverFactory filterChainResolverFactory = new IniFilterChainResolverFactory(ini, defaults);
+            filterChainResolverFactory.setFilterConfig(getFilterConfig());
+            FilterChainResolver resolver = filterChainResolverFactory.getInstance();
+            setFilterChainResolver(resolver);
+        }
+    }
+
+    protected Ini convertConfigToIni(String config) {
+        Ini ini = new Ini();
+        ini.load(config);
+        return ini;
+    }
+
+    protected Ini convertPathToIni(String path) {
+        Ini ini = new Ini();
+        ini.loadFromPath(path);
+        return ini;
+    }
+}

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/IniShiroFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/NameableFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/NameableFilter.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/NameableFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/NameableFilter.java Wed May 26 18:34:28 2010
@@ -1,95 +1,95 @@
-/*
- * 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.servlet;
-
-import org.apache.shiro.util.Nameable;
-
-import javax.servlet.FilterConfig;
-
-/**
- * Allows a filter to be named via JavaBeans-compatible
- * {@link #getName()}/{@link #setName(String)} methods.  If no name is specified, the name of the filter will
- * default to the name given to it in {@code web.xml} (the {@code FilterConfig}'s
- * {@link javax.servlet.FilterConfig#getFilterName() filterName}).
- *
- * @since 1.0
- */
-public abstract class NameableFilter extends AbstractFilter implements Nameable {
-
-    /**
-     * The name of this filter, unique within an application.
-     */
-    private String name;
-
-    /**
-     * Returns the filter's name.
-     * <p/>
-     * Unless overridden by calling the {@link #setName(String) setName(String)} method, this value defaults to the
-     * filter name as specified by the servlet container at start-up:
-     * <pre>
-     * this.name = {@link #getFilterConfig() getFilterConfig()}.{@link javax.servlet.FilterConfig#getFilterName() getName()};</pre>
-     *
-     * @return the filter name, or {@code null} if none available
-     * @see javax.servlet.GenericServlet#getServletName()
-     * @see javax.servlet.FilterConfig#getFilterName()
-     */
-    protected String getName() {
-        if (this.name == null) {
-            FilterConfig config = getFilterConfig();
-            if (config != null) {
-                this.name = config.getFilterName();
-            }
-        }
-
-        return this.name;
-    }
-
-    /**
-     * Sets the filter's name.
-     * <p/>
-     * Unless overridden by calling this method, this value defaults to the filter name as specified by the
-     * servlet container at start-up:
-     * <pre>
-     * this.name = {@link #getFilterConfig() getFilterConfig()}.{@link javax.servlet.FilterConfig#getFilterName() getName()};</pre>
-     *
-     * @param name the name of the filter.
-     */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * Returns a StringBuilder instance with the {@link #getName() name}, or if the name is {@code null}, just the
-     * {@code super.toStringBuilder()} instance.
-     *
-     * @return a StringBuilder instance to use for appending String data that will eventually be returned from a
-     *         {@code toString()} invocation.
-     */
-    protected StringBuilder toStringBuilder() {
-        String name = getName();
-        if (name == null) {
-            return super.toStringBuilder();
-        } else {
-            StringBuilder sb = new StringBuilder();
-            sb.append(name);
-            return sb;
-        }
-    }
-
-}
+/*
+ * 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.servlet;
+
+import org.apache.shiro.util.Nameable;
+
+import javax.servlet.FilterConfig;
+
+/**
+ * Allows a filter to be named via JavaBeans-compatible
+ * {@link #getName()}/{@link #setName(String)} methods.  If no name is specified, the name of the filter will
+ * default to the name given to it in {@code web.xml} (the {@code FilterConfig}'s
+ * {@link javax.servlet.FilterConfig#getFilterName() filterName}).
+ *
+ * @since 1.0
+ */
+public abstract class NameableFilter extends AbstractFilter implements Nameable {
+
+    /**
+     * The name of this filter, unique within an application.
+     */
+    private String name;
+
+    /**
+     * Returns the filter's name.
+     * <p/>
+     * Unless overridden by calling the {@link #setName(String) setName(String)} method, this value defaults to the
+     * filter name as specified by the servlet container at start-up:
+     * <pre>
+     * this.name = {@link #getFilterConfig() getFilterConfig()}.{@link javax.servlet.FilterConfig#getFilterName() getName()};</pre>
+     *
+     * @return the filter name, or {@code null} if none available
+     * @see javax.servlet.GenericServlet#getServletName()
+     * @see javax.servlet.FilterConfig#getFilterName()
+     */
+    protected String getName() {
+        if (this.name == null) {
+            FilterConfig config = getFilterConfig();
+            if (config != null) {
+                this.name = config.getFilterName();
+            }
+        }
+
+        return this.name;
+    }
+
+    /**
+     * Sets the filter's name.
+     * <p/>
+     * Unless overridden by calling this method, this value defaults to the filter name as specified by the
+     * servlet container at start-up:
+     * <pre>
+     * this.name = {@link #getFilterConfig() getFilterConfig()}.{@link javax.servlet.FilterConfig#getFilterName() getName()};</pre>
+     *
+     * @param name the name of the filter.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns a StringBuilder instance with the {@link #getName() name}, or if the name is {@code null}, just the
+     * {@code super.toStringBuilder()} instance.
+     *
+     * @return a StringBuilder instance to use for appending String data that will eventually be returned from a
+     *         {@code toString()} invocation.
+     */
+    protected StringBuilder toStringBuilder() {
+        String name = getName();
+        if (name == null) {
+            return super.toStringBuilder();
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append(name);
+            return sb;
+        }
+    }
+
+}

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/NameableFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/OncePerRequestFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ProxiedFilterChain.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ServletContextSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpServletResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/SimpleCookie.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/mgt/ServletContainerSessionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/mgt/WebSessionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/mgt/WebSessionKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java Wed May 26 18:34:28 2010
@@ -1,160 +1,160 @@
-/*
- * 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.subject;
-
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.subject.Subject;
-import org.apache.shiro.subject.SubjectContext;
-import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
-import org.apache.shiro.web.util.RequestPairSource;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-/**
- * A {@code WebSubject} represents a Subject instance that was acquired as a result of an incoming
- * {@link ServletRequest}.
- *
- * @author Les Hazlewood
- * @since 1.0
- */
-public interface WebSubject extends Subject, RequestPairSource {
-
-    /**
-     * Returns the {@code ServletRequest} accessible when the Subject instance was created.
-     *
-     * @return the {@code ServletRequest} accessible when the Subject instance was created.
-     */
-    ServletRequest getServletRequest();
-
-    /**
-     * Returns the {@code ServletResponse} accessible when the Subject instance was created.
-     *
-     * @return the {@code ServletResponse} accessible when the Subject instance was created.
-     */
-    ServletResponse getServletResponse();
-
-    /**
-     * A {@code WebSubject.Builder} performs the same function as a {@link Subject.Builder Subject.Builder}, but
-     * additionally ensures that the Servlet request/response pair that is triggering the Subject instance's creation
-     * is retained for use by internal Shiro components as necessary.
-     */
-    public static class Builder extends Subject.Builder {
-
-        /**
-         * Constructs a new {@code Web.Builder} instance using the {@link SecurityManager SecurityManager} obtained by
-         * calling {@code SecurityUtils.}{@link SecurityUtils#getSecurityManager() getSecurityManager()}.  If you want
-         * to specify your own SecurityManager instance, use the
-         * {@link #Builder(SecurityManager, ServletRequest, ServletResponse)} constructor instead.
-         *
-         * @param request  the incoming ServletRequest that will be associated with the built {@code WebSubject} instance.
-         * @param response the outgoing ServletRequest paired with the ServletRequest that will be associated with the
-         *                 built {@code WebSubject} instance.
-         */
-        public Builder(ServletRequest request, ServletResponse response) {
-            this(SecurityUtils.getSecurityManager(), request, response);
-        }
-
-        /**
-         * Constructs a new {@code Web.Builder} instance using the specified {@code SecurityManager} instance to
-         * create the {@link WebSubject WebSubject} instance.
-         *
-         * @param securityManager the {@code SecurityManager SecurityManager} instance to use to build the
-         *                        {@code WebSubject} instance.
-         * @param request         the incoming ServletRequest that will be associated with the built {@code WebSubject}
-         *                        instance.
-         * @param response        the outgoing ServletRequest paired with the ServletRequest that will be associated
-         *                        with the built {@code WebSubject} instance.
-         */
-        public Builder(SecurityManager securityManager, ServletRequest request, ServletResponse response) {
-            super(securityManager);
-            if (request == null) {
-                throw new IllegalArgumentException("ServletRequest argument cannot be null.");
-            }
-            if (response == null) {
-                throw new IllegalArgumentException("ServletResponse argument cannot be null.");
-            }
-            setRequest(request);
-            setResponse(response);
-        }
-
-        /**
-         * Overrides the parent implementation to return a new instance of a
-         * {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the additional request/response
-         * pair.
-         *
-         * @return a new instance of a {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the
-         *         additional request/response pair.
-         */
-        @Override
-        protected SubjectContext newSubjectContextInstance() {
-            return new DefaultWebSubjectContext();
-        }
-
-        /**
-         * Called by the {@code WebSubject.Builder} constructor, this method places the request object in the
-         * context map for later retrieval.
-         *
-         * @param request the incoming ServletRequest that triggered the creation of the {@code WebSubject} instance.
-         * @return 'this' for method chaining.
-         */
-        protected Builder setRequest(ServletRequest request) {
-            if (request != null) {
-                ((WebSubjectContext) getSubjectContext()).setServletRequest(request);
-            }
-            return this;
-        }
-
-        /**
-         * Called by the {@code WebSubject.Builder} constructor, this method places the response object in the
-         * context map for later retrieval.
-         *
-         * @param response the outgoing ServletRequest paired with the ServletRequest that triggered the creation of
-         *                 the {@code WebSubject} instance.
-         * @return 'this' for method chaining.
-         */
-        protected Builder setResponse(ServletResponse response) {
-            if (response != null) {
-                ((WebSubjectContext) getSubjectContext()).setServletResponse(response);
-            }
-            return this;
-        }
-
-        /**
-         * Returns {@link #buildSubject() super.buildSubject()}, but additionally ensures that the returned instance
-         * is an {@code instanceof} {@link WebSubject WebSubject} and to support a type-safe method so a caller
-         * does not have to cast.   Per the parent class's method JavaDoc, this method will return a new instance
-         * each time it is called.
-         *
-         * @return a new {@link WebSubject WebSubject} instance built by this {@code Builder}.
-         */
-        public WebSubject buildWebSubject() {
-            Subject subject = super.buildSubject();
-            if (!(subject instanceof WebSubject)) {
-                String msg = "Subject implementation returned from the SecurityManager was not a " +
-                        WebSubject.class.getName() + " implementation.  Please ensure a Web-enabled SecurityManager " +
-                        "has been configured and made available to this builder.";
-                throw new IllegalStateException(msg);
-            }
-            return (WebSubject) subject;
-        }
-    }
-
-}
+/*
+ * 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.subject;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.subject.SubjectContext;
+import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
+import org.apache.shiro.web.util.RequestPairSource;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * A {@code WebSubject} represents a Subject instance that was acquired as a result of an incoming
+ * {@link ServletRequest}.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public interface WebSubject extends Subject, RequestPairSource {
+
+    /**
+     * Returns the {@code ServletRequest} accessible when the Subject instance was created.
+     *
+     * @return the {@code ServletRequest} accessible when the Subject instance was created.
+     */
+    ServletRequest getServletRequest();
+
+    /**
+     * Returns the {@code ServletResponse} accessible when the Subject instance was created.
+     *
+     * @return the {@code ServletResponse} accessible when the Subject instance was created.
+     */
+    ServletResponse getServletResponse();
+
+    /**
+     * A {@code WebSubject.Builder} performs the same function as a {@link Subject.Builder Subject.Builder}, but
+     * additionally ensures that the Servlet request/response pair that is triggering the Subject instance's creation
+     * is retained for use by internal Shiro components as necessary.
+     */
+    public static class Builder extends Subject.Builder {
+
+        /**
+         * Constructs a new {@code Web.Builder} instance using the {@link SecurityManager SecurityManager} obtained by
+         * calling {@code SecurityUtils.}{@link SecurityUtils#getSecurityManager() getSecurityManager()}.  If you want
+         * to specify your own SecurityManager instance, use the
+         * {@link #Builder(SecurityManager, ServletRequest, ServletResponse)} constructor instead.
+         *
+         * @param request  the incoming ServletRequest that will be associated with the built {@code WebSubject} instance.
+         * @param response the outgoing ServletRequest paired with the ServletRequest that will be associated with the
+         *                 built {@code WebSubject} instance.
+         */
+        public Builder(ServletRequest request, ServletResponse response) {
+            this(SecurityUtils.getSecurityManager(), request, response);
+        }
+
+        /**
+         * Constructs a new {@code Web.Builder} instance using the specified {@code SecurityManager} instance to
+         * create the {@link WebSubject WebSubject} instance.
+         *
+         * @param securityManager the {@code SecurityManager SecurityManager} instance to use to build the
+         *                        {@code WebSubject} instance.
+         * @param request         the incoming ServletRequest that will be associated with the built {@code WebSubject}
+         *                        instance.
+         * @param response        the outgoing ServletRequest paired with the ServletRequest that will be associated
+         *                        with the built {@code WebSubject} instance.
+         */
+        public Builder(SecurityManager securityManager, ServletRequest request, ServletResponse response) {
+            super(securityManager);
+            if (request == null) {
+                throw new IllegalArgumentException("ServletRequest argument cannot be null.");
+            }
+            if (response == null) {
+                throw new IllegalArgumentException("ServletResponse argument cannot be null.");
+            }
+            setRequest(request);
+            setResponse(response);
+        }
+
+        /**
+         * Overrides the parent implementation to return a new instance of a
+         * {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the additional request/response
+         * pair.
+         *
+         * @return a new instance of a {@link DefaultWebSubjectContext DefaultWebSubjectContext} to account for the
+         *         additional request/response pair.
+         */
+        @Override
+        protected SubjectContext newSubjectContextInstance() {
+            return new DefaultWebSubjectContext();
+        }
+
+        /**
+         * Called by the {@code WebSubject.Builder} constructor, this method places the request object in the
+         * context map for later retrieval.
+         *
+         * @param request the incoming ServletRequest that triggered the creation of the {@code WebSubject} instance.
+         * @return 'this' for method chaining.
+         */
+        protected Builder setRequest(ServletRequest request) {
+            if (request != null) {
+                ((WebSubjectContext) getSubjectContext()).setServletRequest(request);
+            }
+            return this;
+        }
+
+        /**
+         * Called by the {@code WebSubject.Builder} constructor, this method places the response object in the
+         * context map for later retrieval.
+         *
+         * @param response the outgoing ServletRequest paired with the ServletRequest that triggered the creation of
+         *                 the {@code WebSubject} instance.
+         * @return 'this' for method chaining.
+         */
+        protected Builder setResponse(ServletResponse response) {
+            if (response != null) {
+                ((WebSubjectContext) getSubjectContext()).setServletResponse(response);
+            }
+            return this;
+        }
+
+        /**
+         * Returns {@link #buildSubject() super.buildSubject()}, but additionally ensures that the returned instance
+         * is an {@code instanceof} {@link WebSubject WebSubject} and to support a type-safe method so a caller
+         * does not have to cast.   Per the parent class's method JavaDoc, this method will return a new instance
+         * each time it is called.
+         *
+         * @return a new {@link WebSubject WebSubject} instance built by this {@code Builder}.
+         */
+        public WebSubject buildWebSubject() {
+            Subject subject = super.buildSubject();
+            if (!(subject instanceof WebSubject)) {
+                String msg = "Subject implementation returned from the SecurityManager was not a " +
+                        WebSubject.class.getName() + " implementation.  Please ensure a Web-enabled SecurityManager " +
+                        "has been configured and made available to this builder.";
+                throw new IllegalStateException(msg);
+            }
+            return (WebSubject) subject;
+        }
+    }
+
+}

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubjectContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java
------------------------------------------------------------------------------
    svn:eol-style = native