Coverage Report - org.apache.shiro.web.filter.authz.PortFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
PortFilter
76%
26/34
45%
9/20
3.167
 
 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.authz;
 20  
 
 21  
 import org.apache.shiro.config.ConfigurationException;
 22  
 import org.apache.shiro.util.StringUtils;
 23  
 import org.apache.shiro.web.util.WebUtils;
 24  
 
 25  
 import javax.servlet.ServletRequest;
 26  
 import javax.servlet.ServletResponse;
 27  
 import javax.servlet.http.HttpServletRequest;
 28  
 import java.io.IOException;
 29  
 
 30  
 /**
 31  
  * A Filter that requires the request to be on a specific port, and if not, redirects to the same URL on that port.
 32  
  * <p/>
 33  
  * Example config:
 34  
  * <pre>
 35  
  * [filters]
 36  
  * port.port = 80
 37  
  * <p/>
 38  
  * [urls]
 39  
  * /some/path/** = port
 40  
  * # override for just this path:
 41  
  * /another/path/** = port[8080]
 42  
  * </pre>
 43  
  *
 44  
  * @since 1.0
 45  
  */
 46  102
 public class PortFilter extends AuthorizationFilter {
 47  
 
 48  
     public static final int DEFAULT_HTTP_PORT = 80;
 49  
     public static final String HTTP_SCHEME = "http";
 50  
 
 51  102
     private int port = DEFAULT_HTTP_PORT;
 52  
 
 53  
     public int getPort() {
 54  2
         return port;
 55  
     }
 56  
 
 57  
     public void setPort(int port) {
 58  53
         this.port = port;
 59  53
     }
 60  
 
 61  
     protected int toPort(Object mappedValue) {
 62  2
         String[] ports = (String[]) mappedValue;
 63  2
         if (ports == null || ports.length == 0) {
 64  2
             return getPort();
 65  
         }
 66  0
         if (ports.length > 1) {
 67  0
             throw new ConfigurationException("PortFilter can only be configured with a single port.  You have " +
 68  
                     "configured " + ports.length + ": " + StringUtils.toString(ports));
 69  
         }
 70  0
         return Integer.parseInt(ports[0]);
 71  
     }
 72  
 
 73  
     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
 74  0
         int requiredPort = toPort(mappedValue);
 75  0
         int requestPort = request.getServerPort();
 76  0
         return requiredPort == requestPort;
 77  
     }
 78  
 
 79  
     protected String getScheme(String requestScheme, int port) {
 80  2
         if (port == DEFAULT_HTTP_PORT) {
 81  1
             return HTTP_SCHEME;
 82  1
         } else if (port == SslFilter.DEFAULT_HTTPS_PORT) {
 83  0
             return SslFilter.HTTPS_SCHEME;
 84  
         } else {
 85  1
             return requestScheme;
 86  
         }
 87  
     }
 88  
 
 89  
     /**
 90  
      * Redirects the request to the same exact incoming URL, but with the port listed in the filter's configuration.
 91  
      *
 92  
      * @param request     the incoming <code>ServletRequest</code>
 93  
      * @param response    the outgoing <code>ServletResponse</code>
 94  
      * @param mappedValue the config specified for the filter in the matching request's filter chain.
 95  
      * @return {@code false} always to force a redirect.
 96  
      */
 97  
     @Override
 98  
     protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
 99  
 
 100  
         //just redirect to the specified port:
 101  2
         int port = toPort(mappedValue);
 102  
 
 103  2
         String scheme = getScheme(request.getScheme(), port);
 104  
 
 105  2
         StringBuilder sb = new StringBuilder();
 106  2
         sb.append(scheme).append("://");
 107  2
         sb.append(request.getServerName());
 108  2
         if (port != DEFAULT_HTTP_PORT && port != SslFilter.DEFAULT_HTTPS_PORT) {
 109  1
             sb.append(":");
 110  1
             sb.append(port);
 111  
         }
 112  2
         if (request instanceof HttpServletRequest) {
 113  2
             sb.append(WebUtils.toHttp(request).getRequestURI());
 114  2
             String query = WebUtils.toHttp(request).getQueryString();
 115  2
             if (query != null) {
 116  0
                 sb.append("?").append(query);
 117  
             }
 118  
         }
 119  
 
 120  2
         WebUtils.issueRedirect(request, response, sb.toString());
 121  
 
 122  2
         return false;
 123  
     }
 124  
 }