View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.web.filter.mgt;
20  
21  import org.apache.shiro.config.ConfigurationException;
22  
23  import javax.servlet.Filter;
24  import javax.servlet.FilterChain;
25  import java.util.Map;
26  import java.util.Set;
27  
28  /**
29   * A {@code FilterChainManager} manages the creation and modification of {@link Filter} chains from an available pool
30   * of {@link Filter} instances.
31   *
32   * @since 1.0
33   */
34  public interface FilterChainManager {
35  
36      /**
37       * Returns the pool of available {@code Filter}s managed by this manager, keyed by {@code name}.
38       *
39       * @return the pool of available {@code Filter}s managed by this manager, keyed by {@code name}.
40       */
41      Map<String, Filter> getFilters();
42  
43      /**
44       * Returns the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with
45       * that name.
46       *
47       * @param chainName the name identifying the filter chain.
48       * @return the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with
49       *         that name.
50       */
51      NamedFilterList getChain(String chainName);
52  
53      /**
54       * Returns {@code true} if one or more configured chains are available, {@code false} if none are configured.
55       *
56       * @return {@code true} if one or more configured chains are available, {@code false} if none are configured.
57       */
58      boolean hasChains();
59  
60      /**
61       * Returns the names of all configured chains or an empty {@code Set} if no chains have been configured.
62       *
63       * @return the names of all configured chains or an empty {@code Set} if no chains have been configured.
64       */
65      Set<String> getChainNames();
66  
67      /**
68       * Proxies the specified {@code original} FilterChain with the named chain.  The returned
69       * {@code FilterChain} instance will first execute the configured named chain and then lastly invoke the given
70       * {@code original} chain.
71       *
72       * @param original  the original FilterChain to proxy
73       * @param chainName the name of the internal configured filter chain that should 'sit in front' of the specified
74       *                  original chain.
75       * @return a {@code FilterChain} instance that will execute the named chain and then finally the
76       *         specified {@code original} FilterChain instance.
77       * @throws IllegalArgumentException if there is no configured chain with the given {@code chainName}.
78       */
79      FilterChain proxy(FilterChain original, String chainName);
80  
81      /**
82       * Adds a filter to the 'pool' of available filters that can be used when
83       * {@link #addToChain(String, String, String) creating filter chains}.
84       * <p/>
85       * Calling this method is effectively the same as calling
86       * <code>{@link #addFilter(String, javax.servlet.Filter, boolean) addFilter}(name, filter, <b>false</b>);</code>
87       *
88       * @param name   the name to assign to the filter, used to reference the filter in chain definitions
89       * @param filter the filter to initialize and then add to the pool of available filters that can be used
90       */
91      void addFilter(String name, Filter filter);
92  
93      /**
94       * Adds a filter to the 'pool' of available filters that can be used when
95       * {@link #addToChain(String, String, String) creating filter chains}.
96       *
97       * @param name   the name to assign to the filter, used to reference the filter in chain definitions
98       * @param filter the filter to assign to the filter pool
99       * @param init   whether or not the {@code Filter} should be
100      *               {@link Filter#init(javax.servlet.FilterConfig) initialized} first before being added to the pool.
101      */
102     void addFilter(String name, Filter filter, boolean init);
103 
104     /**
105      * Creates a filter chain for the given {@code chainName} with the specified {@code chainDefinition}
106      * String.
107      * <h3>Conventional Use</h3>
108      * Because the {@code FilterChainManager} interface does not impose any restrictions on filter chain names,
109      * (it expects only Strings), a convenient convention is to make the chain name an actual URL path expression
110      * (such as an {@link org.apache.shiro.util.AntPathMatcher Ant path expression}).  For example:
111      * <p/>
112      * <code>createChain(<b><em>path_expression</em></b>, <em>path_specific_filter_chain_definition</em>);</code>
113      * This convention can be used by a {@link FilterChainResolver} to inspect request URL paths
114      * against the chain name (path) and, if a match is found, return the corresponding chain for runtime filtering.
115      * <h3>Chain Definition Format</h3>
116      * The {@code chainDefinition} method argument is expected to conform to the following format:
117      * <pre>
118      * filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]</pre>
119      * where
120      * <ol>
121      * <li>{@code filterN} is the name of a filter previously
122      * {@link #addFilter(String, javax.servlet.Filter) registered} with the manager, and</li>
123      * <li>{@code [optional_configN]} is an optional bracketed string that has meaning for that particular filter for
124      * <em>this particular chain</em></li>
125      * </ol>
126      * If the filter does not need specific config for that chain name/URL path,
127      * you may discard the brackets - that is, {@code filterN[]} just becomes {@code filterN}.
128      * <p/>
129      * And because this method does create a chain, remember that order matters!  The comma-delimited filter tokens in
130      * the {@code chainDefinition} specify the chain's execution order.
131      * <h3>Examples</h3>
132      * <pre>/account/** = authcBasic</pre>
133      * This example says &quot;Create a filter named '{@code /account/**}' consisting of only the '{@code authcBasic}'
134      * filter&quot;.  Also because the {@code authcBasic} filter does not need any path-specific
135      * config, it doesn't have any config brackets {@code []}.
136      * <p/>
137      * <pre>/remoting/** = authcBasic, roles[b2bClient], perms[&quot;remote:invoke:wan,lan&quot;]</pre>
138      * This example by contrast uses the 'roles' and 'perms' filters which <em>do</em> use bracket notation.  This
139      * definition says:
140      * <p/>
141      * Construct a filter chain named '{@code /remoting/**}' which
142      * <ol>
143      * <li>ensures the user is first authenticated ({@code authcBasic}) then</li>
144      * <li>ensures that user has the {@code b2bClient} role, and then finally</li>
145      * <li>ensures that they have the {@code remote:invoke:lan,wan} permission.</li>
146      * </ol>
147      * <p/>
148      * <b>Note</b>: because elements within brackets [ ] can be comma-delimited themselves, you must quote the
149      * internal bracket definition if commas are needed (the above example has 'lan,wan').  If we didn't do that, the
150      * parser would interpret the chain definition as four tokens:
151      * <ol>
152      * <li>authcBasic</li>
153      * <li>roles[b2bclient]</li>
154      * <li>perms[remote:invoke:lan</li>
155      * <li>wan]</li>
156      * </ol>
157      * which is obviously incorrect.  So remember to use quotes if your internal bracket definitions need to use commas.
158      *
159      * @param chainName       the name to associate with the chain, conventionally a URL path pattern.
160      * @param chainDefinition the string-formatted chain definition used to construct an actual
161      *                        {@link NamedFilterList} chain instance.
162      * @see FilterChainResolver
163      * @see org.apache.shiro.util.AntPathMatcher AntPathMatcher
164      */
165     void createChain(String chainName, String chainDefinition);
166 
167     /**
168      * Adds (appends) a filter to the filter chain identified by the given {@code chainName}.  If there is no chain
169      * with the given name, a new one is created and the filter will be the first in the chain.
170      *
171      * @param chainName  the name of the chain where the filter will be appended.
172      * @param filterName the name of the {@link #addFilter registered} filter to add to the chain.
173      * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered}
174      *                                  filter under the given {@code filterName}
175      */
176     void addToChain(String chainName, String filterName);
177 
178     /**
179      * Adds (appends) a filter to the filter chain identified by the given {@code chainName}.  If there is no chain
180      * with the given name, a new one is created and the filter will be the first in the chain.
181      * <p/>
182      * Note that the final argument expects the associated filter to be an instance of
183      * a {@link org.apache.shiro.web.filter.PathConfigProcessor PathConfigProcessor} to accept per-chain configuration.
184      * If it is not, a {@link IllegalArgumentException} will be thrown.
185      *
186      * @param chainName                 the name of the chain where the filter will be appended.
187      * @param filterName                the name of the {@link #addFilter registered} filter to add to the chain.
188      * @param chainSpecificFilterConfig the filter-specific configuration that should be applied for only the specified
189      *                                  filter chain.
190      * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered}
191      *                                  filter under the given {@code filterName}
192      * @throws ConfigurationException   if the filter is not capable of accepting {@code chainSpecificFilterConfig}
193      *                                  (usually such filters implement the
194      *                                  {@link org.apache.shiro.web.filter.PathConfigProcessor PathConfigProcessor}
195      *                                  interface).
196      */
197     void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) throws ConfigurationException;
198 }