001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.web.filter.mgt; 020 021import org.apache.shiro.config.ConfigurationException; 022import org.apache.shiro.util.AntPathMatcher; 023 024import javax.servlet.Filter; 025import javax.servlet.FilterChain; 026import java.util.List; 027import java.util.Map; 028import java.util.Set; 029 030/** 031 * A {@code FilterChainManager} manages the creation and modification of {@link Filter} chains from an available pool 032 * of {@link Filter} instances. 033 * 034 * @since 1.0 035 */ 036public interface FilterChainManager { 037 038 /** 039 * Returns the pool of available {@code Filter}s managed by this manager, keyed by {@code name}. 040 * 041 * @return the pool of available {@code Filter}s managed by this manager, keyed by {@code name}. 042 */ 043 Map<String, Filter> getFilters(); 044 045 /** 046 * Returns the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with 047 * that name. 048 * 049 * @param chainName the name identifying the filter chain. 050 * @return the filter chain identified by the specified {@code chainName} or {@code null} if there is no chain with 051 * that name. 052 */ 053 NamedFilterList getChain(String chainName); 054 055 /** 056 * Returns {@code true} if one or more configured chains are available, {@code false} if none are configured. 057 * 058 * @return {@code true} if one or more configured chains are available, {@code false} if none are configured. 059 */ 060 boolean hasChains(); 061 062 /** 063 * Returns the names of all configured chains or an empty {@code Set} if no chains have been configured. 064 * 065 * @return the names of all configured chains or an empty {@code Set} if no chains have been configured. 066 */ 067 Set<String> getChainNames(); 068 069 /** 070 * Proxies the specified {@code original} FilterChain with the named chain. The returned 071 * {@code FilterChain} instance will first execute the configured named chain and then lastly invoke the given 072 * {@code original} chain. 073 * 074 * @param original the original FilterChain to proxy 075 * @param chainName the name of the internal configured filter chain that should 'sit in front' of the specified 076 * original chain. 077 * @return a {@code FilterChain} instance that will execute the named chain and then finally the 078 * specified {@code original} FilterChain instance. 079 * @throws IllegalArgumentException if there is no configured chain with the given {@code chainName}. 080 */ 081 FilterChain proxy(FilterChain original, String chainName); 082 083 /** 084 * Adds a filter to the 'pool' of available filters that can be used when 085 * {@link #addToChain(String, String, String) creating filter chains}. 086 * <p/> 087 * Calling this method is effectively the same as calling 088 * <code>{@link #addFilter(String, javax.servlet.Filter, boolean) addFilter}(name, filter, <b>false</b>);</code> 089 * 090 * @param name the name to assign to the filter, used to reference the filter in chain definitions 091 * @param filter the filter to initialize and then add to the pool of available filters that can be used 092 */ 093 void addFilter(String name, Filter filter); 094 095 /** 096 * Adds a filter to the 'pool' of available filters that can be used when 097 * {@link #addToChain(String, String, String) creating filter chains}. 098 * 099 * @param name the name to assign to the filter, used to reference the filter in chain definitions 100 * @param filter the filter to assign to the filter pool 101 * @param init whether or not the {@code Filter} should be 102 * {@link Filter#init(javax.servlet.FilterConfig) initialized} first before being added to the pool. 103 */ 104 void addFilter(String name, Filter filter, boolean init); 105 106 /** 107 * Creates a filter chain for the given {@code chainName} with the specified {@code chainDefinition} 108 * String. 109 * <h3>Conventional Use</h3> 110 * Because the {@code FilterChainManager} interface does not impose any restrictions on filter chain names, 111 * (it expects only Strings), a convenient convention is to make the chain name an actual URL path expression 112 * (such as an {@link AntPathMatcher Ant path expression}). For example: 113 * <p/> 114 * <code>createChain(<b><em>path_expression</em></b>, <em>path_specific_filter_chain_definition</em>);</code> 115 * This convention can be used by a {@link FilterChainResolver} to inspect request URL paths 116 * against the chain name (path) and, if a match is found, return the corresponding chain for runtime filtering. 117 * <h3>Chain Definition Format</h3> 118 * The {@code chainDefinition} method argument is expected to conform to the following format: 119 * <pre> 120 * filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]</pre> 121 * where 122 * <ol> 123 * <li>{@code filterN} is the name of a filter previously 124 * {@link #addFilter(String, javax.servlet.Filter) registered} with the manager, and</li> 125 * <li>{@code [optional_configN]} is an optional bracketed string that has meaning for that particular filter for 126 * <em>this particular chain</em></li> 127 * </ol> 128 * If the filter does not need specific config for that chain name/URL path, 129 * you may discard the brackets - that is, {@code filterN[]} just becomes {@code filterN}. 130 * <p/> 131 * And because this method does create a chain, remember that order matters! The comma-delimited filter tokens in 132 * the {@code chainDefinition} specify the chain's execution order. 133 * <h3>Examples</h3> 134 * <pre>/account/** = authcBasic</pre> 135 * This example says "Create a filter named '{@code /account/**}' consisting of only the '{@code authcBasic}' 136 * filter". Also because the {@code authcBasic} filter does not need any path-specific 137 * config, it doesn't have any config brackets {@code []}. 138 * <p/> 139 * <pre>/remoting/** = authcBasic, roles[b2bClient], perms["remote:invoke:wan,lan"]</pre> 140 * This example by contrast uses the 'roles' and 'perms' filters which <em>do</em> use bracket notation. This 141 * definition says: 142 * <p/> 143 * Construct a filter chain named '{@code /remoting/**}' which 144 * <ol> 145 * <li>ensures the user is first authenticated ({@code authcBasic}) then</li> 146 * <li>ensures that user has the {@code b2bClient} role, and then finally</li> 147 * <li>ensures that they have the {@code remote:invoke:lan,wan} permission.</li> 148 * </ol> 149 * <p/> 150 * <b>Note</b>: because elements within brackets [ ] can be comma-delimited themselves, you must quote the 151 * internal bracket definition if commas are needed (the above example has 'lan,wan'). If we didn't do that, the 152 * parser would interpret the chain definition as four tokens: 153 * <ol> 154 * <li>authcBasic</li> 155 * <li>roles[b2bclient]</li> 156 * <li>perms[remote:invoke:lan</li> 157 * <li>wan]</li> 158 * </ol> 159 * which is obviously incorrect. So remember to use quotes if your internal bracket definitions need to use commas. 160 * 161 * @param chainName the name to associate with the chain, conventionally a URL path pattern. 162 * @param chainDefinition the string-formatted chain definition used to construct an actual 163 * {@link NamedFilterList} chain instance. 164 * @see FilterChainResolver 165 * @see AntPathMatcher AntPathMatcher 166 */ 167 void createChain(String chainName, String chainDefinition); 168 169 /** 170 * Creates a chain that should match any non-matched request paths, 171 * typically {@code /**} assuming an {@link AntPathMatcher} I used. 172 * 173 * @param chainName The name of the chain to create, likely {@code /**}. 174 * @see AntPathMatcher AntPathMatcher 175 * @since 1.6 176 */ 177 void createDefaultChain(String chainName); 178 179 /** 180 * Adds (appends) a filter to the filter chain identified by the given {@code chainName}. If there is no chain 181 * with the given name, a new one is created and the filter will be the first in the chain. 182 * 183 * @param chainName the name of the chain where the filter will be appended. 184 * @param filterName the name of the {@link #addFilter registered} filter to add to the chain. 185 * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered} 186 * filter under the given {@code filterName} 187 */ 188 void addToChain(String chainName, String filterName); 189 190 /** 191 * Adds (appends) a filter to the filter chain identified by the given {@code chainName}. If there is no chain 192 * with the given name, a new one is created and the filter will be the first in the chain. 193 * <p/> 194 * Note that the final argument expects the associated filter to be an instance of 195 * a {@link org.apache.shiro.web.filter.PathConfigProcessor PathConfigProcessor} to accept per-chain configuration. 196 * If it is not, a {@link IllegalArgumentException} will be thrown. 197 * 198 * @param chainName the name of the chain where the filter will be appended. 199 * @param filterName the name of the {@link #addFilter registered} filter to add to the chain. 200 * @param chainSpecificFilterConfig the filter-specific configuration that should be applied for only the specified 201 * filter chain. 202 * @throws IllegalArgumentException if there is not a {@link #addFilter(String, javax.servlet.Filter) registered} 203 * filter under the given {@code filterName} 204 * @throws ConfigurationException if the filter is not capable of accepting {@code chainSpecificFilterConfig} 205 * (usually such filters implement the 206 * {@link org.apache.shiro.web.filter.PathConfigProcessor PathConfigProcessor} 207 * interface). 208 */ 209 void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) throws ConfigurationException; 210 211 /** 212 * Configures the set of named filters that will match all paths. These filters will match BEFORE explicitly 213 * configured filter chains i.e. by calling {@link #createChain(String, String)}, {@link #addToChain(String, String)}, etc. 214 * <br> 215 * <strong>Filters configured in this list wll apply to ALL requests.</strong> 216 * 217 * @param globalFilterNames the list of filter names to match ALL paths. 218 * @throws ConfigurationException if one of the filter names is invalid and cannot be loaded from the set of 219 * configured filters {@link #getFilters()}}. 220 * @since 1.6 221 */ 222 void setGlobalFilters(List<String> globalFilterNames) throws ConfigurationException; 223}