← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17978: enable CORS filter, uses whitelist from system settings

 

------------------------------------------------------------
revno: 17978
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2015-01-14 17:59:10 +0700
message:
  enable CORS filter, uses whitelist from system settings
modified:
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java
  dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java	2014-12-30 23:40:54 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java	2015-01-14 10:59:10 +0000
@@ -30,8 +30,11 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.setting.SystemSettingManager;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -42,6 +45,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.List;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -68,14 +72,13 @@
 
     public static final String CORS_ORIGIN = "Origin";
 
-    private static final String ALLOWED_METHODS = "GET, OPTIONS";
-
-    private static final String ALLOWED_HEADERS = "Accept, Content-Type, Authorization, X-Requested-With";
-
     private static final String EXPOSED_HEADERS = "ETag";
 
     private static final Integer MAX_AGE = 60 * 60; // 1hr max-age
 
+    @Autowired
+    private SystemSettingManager systemSettingManager;
+
     @Override
     public void doFilter( ServletRequest req, ServletResponse res, FilterChain filterChain ) throws IOException, ServletException
     {
@@ -91,7 +94,7 @@
             return;
         }
 
-        if ( !isOriginWhitelisted( origin ) )
+        if ( !isOriginWhitelisted( request, origin ) )
         {
             LOG.warn( "CORS request with origin " + origin + " is not whitelisted." );
             filterChain.doFilter( request, response );
@@ -104,8 +107,11 @@
 
         if ( isPreflight( request ) )
         {
-            response.addHeader( CORS_ALLOW_METHODS, ALLOWED_METHODS );
-            response.addHeader( CORS_ALLOW_HEADERS, ALLOWED_HEADERS );
+            String requestHeaders = request.getHeader( CORS_REQUEST_HEADERS );
+            String requestMethod = request.getHeader( CORS_REQUEST_METHOD );
+
+            response.addHeader( CORS_ALLOW_METHODS, requestMethod );
+            response.addHeader( CORS_ALLOW_HEADERS, requestHeaders );
             response.addHeader( CORS_MAX_AGE, String.valueOf( MAX_AGE ) );
 
             response.setStatus( HttpServletResponse.SC_NO_CONTENT );
@@ -126,10 +132,23 @@
             && !StringUtils.isEmpty( request.getHeader( CORS_REQUEST_METHOD ) );
     }
 
-    private boolean isOriginWhitelisted( String origin )
+    private boolean isOriginWhitelisted( HttpServletRequest request, String origin )
     {
-        // TODO add proper list of whitelisted origins
-        return !StringUtils.isEmpty( origin ) && (origin.startsWith( "http://"; ) || origin.startsWith( "https://"; ));
+        String forwardedProto = request.getHeader( "X-Forwarded-Proto" );
+        String localUrl;
+
+        if ( StringUtils.isEmpty( forwardedProto ) )
+        {
+            localUrl = ServletUriComponentsBuilder.fromContextPath( request ).build().toUriString();
+        }
+        else
+        {
+            localUrl = ServletUriComponentsBuilder.fromContextPath( request )
+                .scheme( forwardedProto ).build().toUriString();
+        }
+
+        List<String> whitelist = systemSettingManager.getCorsWhitelist();
+        return !StringUtils.isEmpty( origin ) && (localUrl.equals( origin ) || whitelist.contains( origin ));
     }
 
     @Override

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml'
--- dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml	2015-01-05 15:53:54 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml	2015-01-14 10:59:10 +0000
@@ -39,7 +39,7 @@
     </sec:headers>
 
     <sec:custom-filter ref="automaticAccessFilter" before="LOGOUT_FILTER" />
-    <!-- <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" /> -->
+    <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" />
     <sec:intercept-url pattern="/api/account/username" access="permitAll()" />
     <sec:intercept-url pattern="/api/account/recovery" access="permitAll()" />
     <sec:intercept-url pattern="/api/account/restore" access="permitAll()" />