details:   https://code.openbravo.com/erp/devel/pi/rev/a0080aeca860
changeset: 30677:a0080aeca860
user:      Martin Taal <martin.taal <at> openbravo.com>
date:      Wed Nov 23 20:55:26 2016 +0100
summary:   Fixes issue 34331: Support pre-defined allowed domains for 
cross-domain requests in a multi-server environment
Implement utility class which supports setting cors headers and checking 
validity of a http origins. Add
cors header setting to main OB servlet.

- AllowedCrossDomainsHandler: new class, main entry point for servlets to set 
cors headers, provides utility methods to check origin validity, calls 
AllowedCrossDomainsChecker classes which implement the actual checking logic. 
The AllowedCrossDomainsChecker can be implemented by a module.
- HttpSecureAppServlet: set cors header and handle the OPTIONS http method

diffstat:

 src/org/openbravo/base/secureApp/AllowedCrossDomainsHandler.java |  129 
++++++++++
 src/org/openbravo/base/secureApp/HttpSecureAppServlet.java       |    9 +
 2 files changed, 138 insertions(+), 0 deletions(-)

diffs (152 lines):

diff -r ce7a1af484d7 -r a0080aeca860 
src/org/openbravo/base/secureApp/AllowedCrossDomainsHandler.java
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/base/secureApp/AllowedCrossDomainsHandler.java  Wed Nov 
23 20:55:26 2016 +0100
@@ -0,0 +1,129 @@
+/*
+ 
************************************************************************************
+ * Copyright (C) 2016 Openbravo S.L.U.
+ * Licensed under the Apache Software License version 2.0
+ * 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.openbravo.base.secureApp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.openbravo.base.weld.WeldUtils;
+
+/**
+ * Provides/handles the domain checkers which determine if a specific cross 
domain request is
+ * allowed on the OB server.
+ * 
+ * https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
+ * 
+ * @author Martin Taal
+ */
+public class AllowedCrossDomainsHandler {
+
+  private static final Logger log = 
Logger.getLogger(AllowedCrossDomainsHandler.class);
+
+  private static AllowedCrossDomainsHandler instance = new 
AllowedCrossDomainsHandler();
+
+  public static AllowedCrossDomainsHandler getInstance() {
+    return instance;
+  }
+
+  public static void setInstance(AllowedCrossDomainsHandler instance) {
+    AllowedCrossDomainsHandler.instance = instance;
+  }
+
+  private Collection<AllowedCrossDomainsChecker> checkers = null;
+
+  /**
+   * Returns true if the origin is allowed, in that case the cors headers can 
be set (
+   * {@link #setCORSHeaders(HttpServletRequest, HttpServletResponse)}.
+   * 
+   * @param request
+   * @param origin
+   *          , the origin can be obtained from the request
+   * @return
+   */
+  public boolean isAllowedOrigin(HttpServletRequest request, String origin) {
+    for (AllowedCrossDomainsChecker checker : getCheckers()) {
+      if (checker.isAllowedOrigin(request, origin)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Collection<AllowedCrossDomainsChecker> getCheckers() {
+    if (checkers == null) {
+      setCheckers();
+    }
+    return checkers;
+  }
+
+  private synchronized void setCheckers() {
+    if (checkers != null) {
+      return;
+    }
+    final Collection<AllowedCrossDomainsChecker> localCheckers = new 
ArrayList<AllowedCrossDomainsChecker>();
+    for (AllowedCrossDomainsChecker checker : WeldUtils
+        .getInstances(AllowedCrossDomainsChecker.class)) {
+      localCheckers.add(checker);
+    }
+    checkers = localCheckers;
+  }
+
+  /**
+   * Utility method to set CORS headers on a request.
+   */
+  public void setCORSHeaders(HttpServletRequest request, HttpServletResponse 
response) {
+
+    try {
+      final String origin = request.getHeader("Origin");
+
+      if (origin != null && !origin.equals("")) {
+
+        if (!isAllowedOrigin(request, origin)) {
+          log.error("Origin " + origin + " is not allowed, request 
information: "
+              + request.getRequestURL() + "-" + request.getQueryString());
+          return;
+        }
+
+        response.setHeader("Access-Control-Allow-Origin", origin);
+        response.setHeader("Access-Control-Allow-Credentials", "true");
+        response.setHeader("Access-Control-Allow-Methods", "POST, GET, 
OPTIONS");
+        response.setHeader("Access-Control-Allow-Headers",
+            "Content-Type, Origin, Accept, X-Requested-With, 
Access-Control-Allow-Credentials");
+
+        response.setHeader("Access-Control-Max-Age", "10000");
+      }
+    } catch (Exception logIt) {
+      // on purpose not stopping on this to retain some robustness
+      log.error(
+          "Error when setting cors headers " + logIt.getMessage() + " " + 
request.getRequestURL()
+              + " " + request.getQueryString(), logIt);
+    }
+  }
+
+  /**
+   * Implementation provided by modules which determine if a request is coming 
from an allowed
+   * origin.
+   * 
+   * @author mtaal
+   */
+  public static abstract class AllowedCrossDomainsChecker {
+
+    public abstract boolean isAllowedOrigin(HttpServletRequest request, String 
origin);
+
+  }
+
+}
diff -r ce7a1af484d7 -r a0080aeca860 
src/org/openbravo/base/secureApp/HttpSecureAppServlet.java
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java        Wed Nov 
23 15:41:24 2016 +0100
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java        Wed Nov 
23 20:55:26 2016 +0100
@@ -164,6 +164,15 @@
   @Override
   public void service(HttpServletRequest request, HttpServletResponse 
response) throws IOException,
       ServletException {
+
+    AllowedCrossDomainsHandler.getInstance().setCORSHeaders(request, response);
+
+    // don't process any further requests otherwise sessions are created for 
OPTIONS
+    // requests, the cors headers have already been set so can return
+    if (request.getMethod().equals("OPTIONS")) {
+      return;
+    }
+
     Variables variables = new Variables(request);
 
     // VariablesSecureApp vars = new VariablesSecureApp(request);

------------------------------------------------------------------------------
_______________________________________________
Openbravo-commits mailing list
Openbravo-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to