From c9b3116b9dcf513af0cc4674518bd910f23f3909 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 23 Jun 2022 12:25:46 -0300 Subject: [PATCH 1/4] Add CORS Filter --- .../java/com/genexus/cors/CORSHelper.java | 32 +++++++++++++++++++ .../java/com/genexus/ws/JAXRSCorsFilter.java | 25 +++++++++++++++ .../java/com/genexus/ws/JAXRSCorsFilter.java | 27 ++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java create mode 100644 wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java create mode 100644 wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java diff --git a/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java b/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java new file mode 100644 index 000000000..3d270bdfc --- /dev/null +++ b/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java @@ -0,0 +1,32 @@ +package com.genexus.cors; + +import java.util.HashMap; + +public class CORSHelper { + private static String CORS_ALLOWED_ORIGINS_ENV_VAR_NAME = "GX_CORS_ALLOW_ORIGIN"; + private static String CORS_MAX_AGE_SECONDS = "86400"; + private static String CORS_ALLOWED_METHODS = "GET, POST, PUT, DELETE, OPTIONS, HEAD"; + private static String CORS_ALLOWED_HEADERS = "*"; + + public static HashMap getCORSHeaders() { + String corsAllowedOrigin = System.getenv(CORS_ALLOWED_ORIGINS_ENV_VAR_NAME); + if (corsAllowedOrigin == null || corsAllowedOrigin.isEmpty()) { + return null; + } + HashMap corsHeaders = new HashMap<>(); + corsHeaders.put( + "Access-Control-Allow-Origin", corsAllowedOrigin); + corsHeaders.put( + "Access-Control-Allow-Credentials", "true"); + corsHeaders.put( + "Access-Control-Allow-Headers", + CORS_ALLOWED_HEADERS); + corsHeaders.put( + "Access-Control-Allow-Methods", + CORS_ALLOWED_METHODS); + corsHeaders.put( + "Access-Control-Max-Age", + CORS_MAX_AGE_SECONDS); + return corsHeaders; + } +} diff --git a/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java new file mode 100644 index 000000000..a8e19e763 --- /dev/null +++ b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -0,0 +1,25 @@ +package com.genexus.ws; + +import com.genexus.cors.CORSHelper; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerResponseContext; +import jakarta.ws.rs.container.ContainerResponseFilter; +import jakarta.ws.rs.ext.Provider; +import java.util.HashMap; + +@Provider +public class JAXRSCorsFilter implements ContainerResponseFilter { + @Override + public void filter(ContainerRequestContext requestContext, + ContainerResponseContext responseContext) { + HashMap corsHeaders = CORSHelper.getCORSHeaders(); + if (corsHeaders == null) { + return; + } + for (String headerName : corsHeaders.keySet()) { + if (!responseContext.getHeaders().containsKey(headerName)) { + responseContext.getHeaders().add(headerName, corsHeaders.get(headerName)); + } + } + } +} diff --git a/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java new file mode 100644 index 000000000..47a32fbc5 --- /dev/null +++ b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -0,0 +1,27 @@ +package com.genexus.ws; + +import com.genexus.cors.CORSHelper; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.ext.Provider; +import java.util.HashMap; + +@Provider +public class JAXRSCorsFilter implements ContainerResponseFilter { + + @Override + public void filter(ContainerRequestContext requestContext, + ContainerResponseContext responseContext) { + HashMap corsHeaders = CORSHelper.getCORSHeaders(); + if (corsHeaders == null) { + return; + } + for (String headerName : corsHeaders.keySet()) { + if (!responseContext.getHeaders().containsKey(headerName)) { + responseContext.getHeaders().add(headerName, corsHeaders.get(headerName)); + } + } + } +} From de3ba9a283e7b80bef7bb6f00fe334b95ee963e8 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 7 Jul 2022 18:00:31 -0300 Subject: [PATCH 2/4] Add CorsFilter for old plain webservices that are served through servlet and not JAXRS. --- .../java/com/genexus/cors/CORSHelper.java | 8 ++-- .../java/com/genexus/servlet/CorsFilter.java | 46 +++++++++++++++++++ .../java/com/genexus/ws/JAXRSCorsFilter.java | 2 +- .../java/com/genexus/servlet/CorsFilter.java | 43 +++++++++++++++++ .../java/com/genexus/ws/JAXRSCorsFilter.java | 2 +- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java create mode 100644 wrapperjavax/src/main/java/com/genexus/servlet/CorsFilter.java diff --git a/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java b/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java index 3d270bdfc..f1c700d75 100644 --- a/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java +++ b/wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java @@ -5,10 +5,10 @@ public class CORSHelper { private static String CORS_ALLOWED_ORIGINS_ENV_VAR_NAME = "GX_CORS_ALLOW_ORIGIN"; private static String CORS_MAX_AGE_SECONDS = "86400"; - private static String CORS_ALLOWED_METHODS = "GET, POST, PUT, DELETE, OPTIONS, HEAD"; + private static String CORS_ALLOWED_METHODS = "GET, POST, PUT, DELETE, HEAD"; private static String CORS_ALLOWED_HEADERS = "*"; - public static HashMap getCORSHeaders() { + public static HashMap getCORSHeaders(String requestRequiredHeaders) { String corsAllowedOrigin = System.getenv(CORS_ALLOWED_ORIGINS_ENV_VAR_NAME); if (corsAllowedOrigin == null || corsAllowedOrigin.isEmpty()) { return null; @@ -18,9 +18,11 @@ public static HashMap getCORSHeaders() { "Access-Control-Allow-Origin", corsAllowedOrigin); corsHeaders.put( "Access-Control-Allow-Credentials", "true"); + corsHeaders.put( "Access-Control-Allow-Headers", - CORS_ALLOWED_HEADERS); + requestRequiredHeaders == null || requestRequiredHeaders.isEmpty() ? CORS_ALLOWED_HEADERS : requestRequiredHeaders); + corsHeaders.put( "Access-Control-Allow-Methods", CORS_ALLOWED_METHODS); diff --git a/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java b/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java new file mode 100644 index 000000000..2d5d7b24d --- /dev/null +++ b/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java @@ -0,0 +1,46 @@ +package com.genexus.servlet; + + +import com.genexus.cors.CORSHelper; +import jakarta.servlet.*; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.HashMap; + +public class CorsFilter implements jakarta.servlet.Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + Filter.super.init(filterConfig); + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + + HashMap corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers")); + if (corsHeaders != null) { + HttpServletResponse response = (HttpServletResponse) servletResponse; + for (String headerName : corsHeaders.keySet()) { + if (!response.containsHeader(headerName)) { + response.setHeader(headerName, corsHeaders.get(headerName)); + } + } + } + if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { + filterChain.doFilter(servletRequest, servletResponse); + } + } + + @Override + public void destroy() { + Filter.super.destroy(); + } +} diff --git a/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java index a8e19e763..662b6e521 100644 --- a/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java +++ b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -12,7 +12,7 @@ public class JAXRSCorsFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { - HashMap corsHeaders = CORSHelper.getCORSHeaders(); + HashMap corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers")); if (corsHeaders == null) { return; } diff --git a/wrapperjavax/src/main/java/com/genexus/servlet/CorsFilter.java b/wrapperjavax/src/main/java/com/genexus/servlet/CorsFilter.java new file mode 100644 index 000000000..043194ae7 --- /dev/null +++ b/wrapperjavax/src/main/java/com/genexus/servlet/CorsFilter.java @@ -0,0 +1,43 @@ +package com.genexus.servlet; + +import com.genexus.cors.CORSHelper; + +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.HashMap; + +public class CorsFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HashMap corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers")); + if (corsHeaders != null) { + HttpServletResponse response = (HttpServletResponse) servletResponse; + for (String headerName : corsHeaders.keySet()) { + if (!response.containsHeader(headerName)) { + response.setHeader(headerName, corsHeaders.get(headerName)); + } + } + } + if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { + filterChain.doFilter(servletRequest, servletResponse); + } + } + + @Override + public void destroy() { + + } +} diff --git a/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java index 47a32fbc5..e44cb1fa0 100644 --- a/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java +++ b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -14,7 +14,7 @@ public class JAXRSCorsFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { - HashMap corsHeaders = CORSHelper.getCORSHeaders(); + HashMap corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers")); if (corsHeaders == null) { return; } From 0c5033031c0e91fccaa782619b5a125dfdf72fe0 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 8 Jul 2022 10:33:09 -0300 Subject: [PATCH 3/4] Adjust Http Headers for CORS --- .../src/main/java/com/genexus/ws/JAXRSCorsFilter.java | 6 +++--- .../src/main/java/com/genexus/ws/JAXRSCorsFilter.java | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java index 662b6e521..bad0e4f0c 100644 --- a/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java +++ b/wrapperjakarta/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -5,6 +5,8 @@ import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.ext.Provider; + +import java.util.Collections; import java.util.HashMap; @Provider @@ -17,9 +19,7 @@ public void filter(ContainerRequestContext requestContext, return; } for (String headerName : corsHeaders.keySet()) { - if (!responseContext.getHeaders().containsKey(headerName)) { - responseContext.getHeaders().add(headerName, corsHeaders.get(headerName)); - } + responseContext.getHeaders().putSingle(headerName,corsHeaders.get(headerName)); } } } diff --git a/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java index e44cb1fa0..765d8724d 100644 --- a/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java +++ b/wrapperjavax/src/main/java/com/genexus/ws/JAXRSCorsFilter.java @@ -6,6 +6,7 @@ import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.Provider; +import java.util.Collections; import java.util.HashMap; @Provider @@ -19,9 +20,7 @@ public void filter(ContainerRequestContext requestContext, return; } for (String headerName : corsHeaders.keySet()) { - if (!responseContext.getHeaders().containsKey(headerName)) { - responseContext.getHeaders().add(headerName, corsHeaders.get(headerName)); - } + responseContext.getHeaders().putSingle(headerName,corsHeaders.get(headerName)); } } } From cc3e354d552785b37d7e0bfeffd898f223d2e484 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 8 Jul 2022 10:45:12 -0300 Subject: [PATCH 4/4] Do not call superclass --- .../src/main/java/com/genexus/servlet/CorsFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java b/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java index 2d5d7b24d..7efb59baa 100644 --- a/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java +++ b/wrapperjakarta/src/main/java/com/genexus/servlet/CorsFilter.java @@ -18,7 +18,7 @@ public class CorsFilter implements jakarta.servlet.Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { - Filter.super.init(filterConfig); + } @Override @@ -41,6 +41,6 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo @Override public void destroy() { - Filter.super.destroy(); + } }