Author: jacopoc
Date: Wed Sep 14 15:29:53 2016 New Revision: 1760725 URL: http://svn.apache.org/viewvc?rev=1760725&view=rev Log: Implemented: New servlet filter that provides all the "controller" related logic currently available in the ContextFilter. At the moment the filter is not used but, once the "controller" logic will be removed by the ContextFilter, the applications' web.xml files will be updated to deploy the two filters in a chain: * ControlFilter will filter and redirect requests * ContextFilter will set the required objects in the contexts (session and request) like the delegator, dispatcher etc... This separation of concerns will make the deplyment more flexible when additional filters are required. While the logic in this new filter is functionally mostly the same of that currently in ContextFilter, this new implementation is more efficient and the behavior and configuration parameters are clearly discribed. Added: ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java (with props) Added: ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java?rev=1760725&view=auto ============================================================================== --- ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java (added) +++ ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java Wed Sep 14 15:29:53 2016 @@ -0,0 +1,165 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.apache.ofbiz.webapp.control; + +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.StringUtil; +import org.apache.ofbiz.base.util.UtilValidate; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.HashSet; + +/* + * A Filter used to specify a whitelist of allowed paths to the OFBiz application. + * Requests that do not match any of the paths listed in allowedPaths are redirected to redirectPath, or an error code + * is returned (the error code can be set in errorCode, the default value is 403). + * If forceRedirectAll is set to Y then allowedPaths is ignored and all requests are redirected to redirectPath; note + * that forceRedirectAll is ignored if redirectPath is not set. + * + * Init parameters: + * - forceRedirectAll: when set to Y, and redirectPath is set, then redirects all traffic to redirectPath + * - allowedPaths: a colon separated list of URL or URI that are allowed; + * non matching request paths are redirected, or an error code is returned, + * according to the setup of redirectPath and errorCode + * - redirectPath: if the path requested is not in the allowedPaths, or forceRedirectAll is set to Y, + * specifies the the path to which the request is redirected to; + * - errorCode: the error code set in the response if the path requested is not in the allowedPaths + * and redirectPath is not set; defaults to 403 + * + * Interaction with the context: + * - for its internal logic (to avoid an infinite loop of redirections when forceRedirectAll is set) the filter sets + * a session parameter (_FORCE_REDIRECT_=true) before the first redirection; the parameter is removed during the + * second pass before the request is forwarded to the next filter in the chain + * - the filter skips the check against the whitelist of allowed paths if a request attribute + * with name _FORWARDED_FROM_SERVLET_ is present; this attribute is typically set by the ControlServlet to indicate + * that the request path is safe and should not be checked again + */ + + +public class ControlFilter implements Filter { + public static final String FORWARDED_FROM_SERVLET = "_FORWARDED_FROM_SERVLET_"; + + private static final String module = ControlFilter.class.getName(); + private boolean redirectAll; + private boolean redirectPathIsUrl; + private String redirectPath; + private int errorCode; + private Set<String> allowedPaths = new HashSet<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + redirectPath = filterConfig.getInitParameter("redirectPath"); + redirectPathIsUrl = (redirectPath != null && redirectPath.toLowerCase().startsWith("http")); + String redirectAllString = filterConfig.getInitParameter("forceRedirectAll"); + redirectAll = (redirectPath != null && redirectAllString != null && "Y".equalsIgnoreCase(redirectAllString)); + String errorCodeString = filterConfig.getInitParameter("errorCode"); + errorCode = 403; + if (UtilValidate.isNotEmpty(errorCodeString)) { + try { + errorCode = Integer.parseInt(errorCodeString); + } catch (NumberFormatException nfe) { + Debug.logWarning(nfe, "Error code specified would not parse to Integer: " + errorCodeString, module); + Debug.logWarning(nfe, "The default error code will be used: " + errorCode, module); + } + } + String allowedPath = filterConfig.getInitParameter("allowedPaths"); + List<String> allowList; + if ((allowList = StringUtil.split(allowedPath, ":")) != null) { + if (redirectPath != null && !redirectPathIsUrl) { + // if an URI is specified in the redirectPath parameter, it is added to the allowed list + allowList.add(redirectPath); + } + allowedPaths.addAll(allowList); + } + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + // check if we are told to redirect everything + if (redirectAll) { + // little trick here so we don't loop on ourselves + if (httpRequest.getSession().getAttribute("_FORCE_REDIRECT_") == null) { + httpRequest.getSession().setAttribute("_FORCE_REDIRECT_", "true"); + Debug.logWarning("Redirecting user to: " + redirectPath, module); + if (redirectPathIsUrl) { + httpResponse.sendRedirect(redirectPath); + } else { + httpResponse.sendRedirect(httpRequest.getContextPath() + redirectPath); + } + return; + } else { + httpRequest.getSession().removeAttribute("_FORCE_REDIRECT_"); + chain.doFilter(httpRequest, httpResponse); + return; + } + } + + if (httpRequest.getAttribute(FORWARDED_FROM_SERVLET) == null && !allowedPaths.isEmpty()) { + // check to make sure the requested url is allowed + // get the request URI without the webapp mount point + String requestUri = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()); + int offset = requestUri.indexOf("/", 1); + if (offset == -1) { + offset = requestUri.length(); + } + while (!allowedPaths.contains(requestUri.substring(0, offset))) { + offset = requestUri.indexOf("/", offset + 1); + if (offset == -1) { + if (allowedPaths.contains(requestUri)) { + break; + } + // path not allowed + if (redirectPath == null) { + httpResponse.sendError(errorCode, httpRequest.getRequestURI()); + } else { + if (redirectPathIsUrl) { + httpResponse.sendRedirect(redirectPath); + } else { + httpResponse.sendRedirect(httpRequest.getContextPath() + redirectPath); + } + } + if (Debug.infoOn()) { + Debug.logInfo("[Filtered request]: " + httpRequest.getRequestURI() + " --> " + (redirectPath == null? errorCode: redirectPath), module); + } + return; + } + } + chain.doFilter(request, httpResponse); + } + } + + @Override + public void destroy() { + + } +} Propchange: ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain |
Free forum by Nabble | Edit this page |