File Source: SchemeEnforcementFilter.java

     1  /*
     2  * Licensed to the Apache Software Foundation (ASF) under one or more
     3  *  contributor license agreements.  The ASF licenses this file to You
     4  * under the Apache License, Version 2.0 (the "License"); you may not
     5  * use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *     http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.  For additional information regarding
    15  * copyright in this work, please see the NOTICE file in the top level
    16  * directory of this distribution.
    17  */
    18  /*
    19   * SchemeEnforcementFilter.java
    20   *
    21   * Created on September 16, 2005, 3:17 PM
    22   */
    23  
    24  package org.apache.roller.weblogger.ui.core.filters;
    25  
    26  import java.io.IOException;
    27  import java.util.HashSet;
    28  import java.util.Iterator;
    29  import java.util.Set;
    30  import javax.servlet.Filter;
    31  import javax.servlet.FilterChain;
    32  import javax.servlet.FilterConfig;
    33  import javax.servlet.ServletException;
    34  import javax.servlet.ServletRequest;
    35  import javax.servlet.ServletResponse;
    36  import javax.servlet.http.HttpServletRequest;
    37  import javax.servlet.http.HttpServletResponse;
    38  import org.apache.commons.logging.Log;
    39  import org.apache.commons.logging.LogFactory;
    40  import org.apache.roller.weblogger.config.WebloggerConfig;
    41  
    42  
    43  /**
    44   * The SchemeEnforcementFilter is provided for Roller sites that enable secure
    45   * logins and want to ensure that only login urls are used under https.
    46   *
    47   * @author  Allen Gilliland
    48   *
    49   * @web.filter name="SchemeEnforcementFilter"
    50   */
         /* 
    P/P   *  Method: void org.apache.roller.weblogger.ui.core.filters.SchemeEnforcementFilter()
          * 
          *  Postconditions:
          *    this.allowedUrls == &new HashSet(SchemeEnforcementFilter#1)
          *    this.filterConfig == null
          *    this.httpsHeaderName == null
          *    this.httpsHeaderValue == null
          *    this.httpPort == 80
          *    this.httpsPort == 443
          *    this.schemeEnforcementEnabled == 0
          *    this.secureLoginEnabled == 0
          *    new HashSet(SchemeEnforcementFilter#1) num objects == 1
          */
    51  public class SchemeEnforcementFilter implements Filter {
    52      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.core.filters.SchemeEnforcementFilter__static_init
              * 
              *  Postconditions:
              *    init'ed(mLogger)
              */
    53      private static Log mLogger = 
    54              LogFactory.getLog(SchemeEnforcementFilter.class);
    55      
    56      private FilterConfig filterConfig = null;
    57      
    58      private boolean schemeEnforcementEnabled = false;
    59      private boolean secureLoginEnabled = false;
    60      private int httpPort = 80;
    61      private int httpsPort = 443;
    62      private String httpsHeaderName = null;
    63      private String httpsHeaderValue = null;
    64      
    65      private Set allowedUrls = new HashSet();
    66      
    67      
    68      /**
    69       * Process filter.
    70       *
    71       * We'll take the incoming request and first determine if this is a
    72       * secure request.  If the request is secure then we'll see if it matches
    73       * one of the allowed secure urls, if not then we will redirect back out
    74       * of https.
    75       */
    76      public void doFilter(ServletRequest request, ServletResponse response,
    77                          FilterChain chain)
    78              throws IOException, ServletException {
    79          
                 /* 
    P/P           *  Method: void doFilter(ServletRequest, ServletResponse, FilterChain)
                  * 
                  *  Preconditions:
                  *    init'ed(this.schemeEnforcementEnabled)
                  *    (soft) chain != null
                  *    (soft) mLogger != null
                  *    (soft) request != null
                  *    (soft) response != null
                  *    (soft) this.allowedUrls != null
                  *    (soft) init'ed(this.httpPort)
                  *    (soft) init'ed(this.httpsPort)
                  *    (soft) init'ed(this.secureLoginEnabled)
                  * 
                  *  Test Vectors:
                  *    this.httpPort: {80}, {-231..79, 81..232-1}
                  *    this.httpsPort: {443}, {-231..442, 444..232-1}
                  *    this.schemeEnforcementEnabled: {0}, {1}
                  *    this.secureLoginEnabled: {0}, {1}
                  *    java.util.Set:contains(...)@103: {1}, {0}
                  *    java.util.Set:contains(...)@87: {0}, {1}
                  *    javax.servlet.ServletRequest:isSecure(...)@103: {0}, {1}
                  *    javax.servlet.ServletRequest:isSecure(...)@87: {1}, {0}
                  *    javax.servlet.http.HttpServletRequest:getQueryString(...)@112: Addr_Set{null}, Inverse{null}
                  *    javax.servlet.http.HttpServletRequest:getQueryString(...)@96: Addr_Set{null}, Inverse{null}
                  */
    80          if(this.schemeEnforcementEnabled && this.secureLoginEnabled) {
    81              
    82              HttpServletRequest req = (HttpServletRequest) request;
    83              HttpServletResponse res = (HttpServletResponse) response;
    84              
    85              mLogger.debug("checking path = "+req.getServletPath());
    86              
    87              if(!request.isSecure() && allowedUrls.contains(req.getServletPath())) {
    88                  // http insecure request that should be over https
    89                  String redirect = "https://"+req.getServerName();
    90                  
    91                  if(this.httpsPort != 443)
    92                      redirect += ":"+this.httpsPort;
    93                  
    94                  redirect += req.getRequestURI();
    95                  
    96                  if(req.getQueryString() != null)
    97                      redirect += "?"+req.getQueryString();
    98                  
    99                  mLogger.debug("Redirecting to "+redirect);
   100                  res.sendRedirect(redirect);
   101                  return;
   102                  
   103              } else if(request.isSecure() && !allowedUrls.contains(req.getServletPath())) {
   104                  // https secure request that should be over http
   105                  String redirect = "http://"+req.getServerName();
   106                  
   107                  if(this.httpPort != 80)
   108                      redirect += ":"+this.httpPort;
   109                  
   110                  redirect += req.getRequestURI();
   111                  
   112                  if(req.getQueryString() != null)
   113                      redirect += "?"+req.getQueryString();
   114                  
   115                  mLogger.debug("Redirecting to "+redirect);
   116                  res.sendRedirect(redirect);
   117                  return;
   118              }
   119          }
   120          
   121          chain.doFilter(request, response);
   122      }
   123      
   124      
             /* 
    P/P       *  Method: void destroy()
              */
   125      public void destroy() {}
   126      
   127      
   128      /**
   129       * Filter init.
   130       *
   131       * We are just collecting init properties which we'll use for each request.
   132       */
   133      public void init(FilterConfig filterConfig) {
                 /* 
    P/P           *  Method: void init(FilterConfig)
                  * 
                  *  Preconditions:
                  *    (soft) mLogger != null
                  *    (soft) this.allowedUrls != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getProperty(...)@158 != null
                  * 
                  *  Postconditions:
                  *    this.filterConfig == filterConfig
                  *    init'ed(this.filterConfig)
                  *    possibly_updated(this.httpPort)
                  *    possibly_updated(this.httpsPort)
                  *    init'ed(this.schemeEnforcementEnabled)
                  *    init'ed(this.secureLoginEnabled)
                  * 
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@168: {0}, {1}
                  *    org.apache.commons.logging.Log:isDebugEnabled(...)@166: {0}, {1}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@137: {0}, {1}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@139: {0}, {1}
                  */
   134          this.filterConfig = filterConfig;
   135          
   136          // determine if we are doing scheme enforcement
   137          this.schemeEnforcementEnabled = 
   138                  WebloggerConfig.getBooleanProperty("schemeenforcement.enabled");
   139          this.secureLoginEnabled = 
   140                  WebloggerConfig.getBooleanProperty("securelogin.enabled");
   141          
   142          if(this.schemeEnforcementEnabled && this.secureLoginEnabled) {
   143              // gather some more properties
   144              String http_port = 
   145                      WebloggerConfig.getProperty("securelogin.http.port");
   146              String https_port = 
   147                      WebloggerConfig.getProperty("securelogin.https.port");
   148              
   149              try {
   150                  this.httpPort = Integer.parseInt(http_port);
   151                  this.httpsPort = Integer.parseInt(https_port);
   152              } catch(NumberFormatException nfe) {
   153                  // ignored ... guess we'll have to use the defaults
   154                  mLogger.warn("error with secure login ports", nfe);
   155              }
   156              
   157              // finally, construct our list of allowable https urls
   158              String urls = 
   159                      WebloggerConfig.getProperty("schemeenforcement.https.urls");
   160              String[] urlsArray = urls.split(",");
+  161              for(int i=0; i < urlsArray.length; i++)
+  162                  this.allowedUrls.add(urlsArray[i]);
   163              
   164              // some logging for the curious
   165              mLogger.info("Scheme enforcement = enabled");
   166              if(mLogger.isDebugEnabled()) {
   167                  mLogger.debug("allowed urls are:");
   168                  for(Iterator it = this.allowedUrls.iterator(); it.hasNext();)
   169                      mLogger.debug(it.next());
   170              }
   171          }
   172      }
   173      
   174  }








SofCheck Inspector Build Version : 2.18479
SchemeEnforcementFilter.java 2009-Jan-02 14:25:14
SchemeEnforcementFilter.class 2009-Sep-04 03:12:44