Coverage Report - org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
PathMatchingFilterChainResolver
100%
29/29
87%
7/8
1.667
 
 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.util.AntPathMatcher;
 22  
 import org.apache.shiro.util.PatternMatcher;
 23  
 import org.apache.shiro.web.util.WebUtils;
 24  
 import org.slf4j.Logger;
 25  
 import org.slf4j.LoggerFactory;
 26  
 
 27  
 import javax.servlet.FilterChain;
 28  
 import javax.servlet.FilterConfig;
 29  
 import javax.servlet.ServletRequest;
 30  
 import javax.servlet.ServletResponse;
 31  
 
 32  
 /**
 33  
  * A {@code FilterChainResolver} that resolves {@link FilterChain}s based on url path
 34  
  * matching, as determined by a configurable {@link #setPathMatcher(org.apache.shiro.util.PatternMatcher) PathMatcher}.
 35  
  * <p/>
 36  
  * This implementation functions by consulting a {@link org.apache.shiro.web.filter.mgt.FilterChainManager} for all configured filter chains (keyed
 37  
  * by configured path pattern).  If an incoming Request path matches one of the configured path patterns (via
 38  
  * the {@code PathMatcher}, the corresponding configured {@code FilterChain} is returned.
 39  
  *
 40  
  * @since 1.0
 41  
  */
 42  
 public class PathMatchingFilterChainResolver implements FilterChainResolver {
 43  
 
 44  2
     private static transient final Logger log = LoggerFactory.getLogger(PathMatchingFilterChainResolver.class);
 45  
 
 46  
     private FilterChainManager filterChainManager;
 47  
 
 48  
     private PatternMatcher pathMatcher;
 49  
 
 50  22
     public PathMatchingFilterChainResolver() {
 51  22
         this.pathMatcher = new AntPathMatcher();
 52  22
         this.filterChainManager = new DefaultFilterChainManager();
 53  22
     }
 54  
 
 55  10
     public PathMatchingFilterChainResolver(FilterConfig filterConfig) {
 56  10
         this.pathMatcher = new AntPathMatcher();
 57  10
         this.filterChainManager = new DefaultFilterChainManager(filterConfig);
 58  10
     }
 59  
 
 60  
     /**
 61  
      * Returns the {@code PatternMatcher} used when determining if an incoming request's path
 62  
      * matches a configured filter chain.  Unless overridden, the
 63  
      * default implementation is an {@link org.apache.shiro.util.AntPathMatcher AntPathMatcher}.
 64  
      *
 65  
      * @return the {@code PatternMatcher} used when determining if an incoming request's path
 66  
      *         matches a configured filter chain.
 67  
      */
 68  
     public PatternMatcher getPathMatcher() {
 69  20
         return pathMatcher;
 70  
     }
 71  
 
 72  
     /**
 73  
      * Sets the {@code PatternMatcher} used when determining if an incoming request's path
 74  
      * matches a configured filter chain.  Unless overridden, the
 75  
      * default implementation is an {@link org.apache.shiro.util.AntPathMatcher AntPathMatcher}.
 76  
      *
 77  
      * @param pathMatcher the {@code PatternMatcher} used when determining if an incoming request's path
 78  
      *                    matches a configured filter chain.
 79  
      */
 80  
     public void setPathMatcher(PatternMatcher pathMatcher) {
 81  2
         this.pathMatcher = pathMatcher;
 82  2
     }
 83  
 
 84  
     public FilterChainManager getFilterChainManager() {
 85  44
         return filterChainManager;
 86  
     }
 87  
 
 88  
     @SuppressWarnings({"UnusedDeclaration"})
 89  
     public void setFilterChainManager(FilterChainManager filterChainManager) {
 90  2
         this.filterChainManager = filterChainManager;
 91  2
     }
 92  
 
 93  
     public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
 94  10
         FilterChainManager filterChainManager = getFilterChainManager();
 95  10
         if (!filterChainManager.hasChains()) {
 96  2
             return null;
 97  
         }
 98  
 
 99  8
         String requestURI = getPathWithinApplication(request);
 100  
 
 101  
         //the 'chain names' in this implementation are actually path patterns defined by the user.  We just use them
 102  
         //as the chain name for the FilterChainManager's requirements
 103  8
         for (String pathPattern : filterChainManager.getChainNames()) {
 104  
 
 105  
             // If the path does match, then pass on to the subclass implementation for specific checks:
 106  8
             if (pathMatches(pathPattern, requestURI)) {
 107  6
                 if (log.isTraceEnabled()) {
 108  6
                     log.trace("Matched path pattern [" + pathPattern + "] for requestURI [" + requestURI + "].  " +
 109  
                             "Utilizing corresponding filter chain...");
 110  
                 }
 111  6
                 return filterChainManager.proxy(originalChain, pathPattern);
 112  
             }
 113  2
         }
 114  
 
 115  2
         return null;
 116  
     }
 117  
 
 118  
     /**
 119  
      * Returns {@code true} if an incoming request path (the {@code path} argument)
 120  
      * matches a configured filter chain path (the {@code pattern} argument), {@code false} otherwise.
 121  
      * <p/>
 122  
      * Simply delegates to
 123  
      * <b><code>{@link #getPathMatcher() getPathMatcher()}.{@link org.apache.shiro.util.PatternMatcher#matches(String, String) matches(pattern,path)}</code></b>.
 124  
      * Subclass implementors should think carefully before overriding this method, as typically a custom
 125  
      * {@code PathMatcher} should be configured for custom path matching behavior instead.  Favor OO composition
 126  
      * rather than inheritance to limit your exposure to Shiro implementation details which may change over time.
 127  
      *
 128  
      * @param pattern the pattern to match against
 129  
      * @param path    the value to match with the specified {@code pattern}
 130  
      * @return {@code true} if the request {@code path} matches the specified filter chain url {@code pattern},
 131  
      *         {@code false} otherwise.
 132  
      */
 133  
     protected boolean pathMatches(String pattern, String path) {
 134  8
         PatternMatcher pathMatcher = getPathMatcher();
 135  8
         return pathMatcher.matches(pattern, path);
 136  
     }
 137  
 
 138  
     /**
 139  
      * Merely returns
 140  
      * <code>WebUtils.{@link org.apache.shiro.web.util.WebUtils#getPathWithinApplication(javax.servlet.http.HttpServletRequest) getPathWithinApplication(request)}</code>
 141  
      * and can be overridden by subclasses for custom request-to-application-path resolution behavior.
 142  
      *
 143  
      * @param request the incoming {@code ServletRequest}
 144  
      * @return the request's path within the appliation.
 145  
      */
 146  
     protected String getPathWithinApplication(ServletRequest request) {
 147  8
         return WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
 148  
     }
 149  
 }