Skip to content

Commit a9d7883

Browse files
authored
Add CORS Headers to JAX Webservice Responses when Environment Variable is Present (#585)
* Add CORS Filter * Add CorsFilter for old plain webservices that are served through servlet and not JAXRS. * Adjust Http Headers for CORS * Do not call superclass
1 parent d3d3dee commit a9d7883

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.genexus.cors;
2+
3+
import java.util.HashMap;
4+
5+
public class CORSHelper {
6+
private static String CORS_ALLOWED_ORIGINS_ENV_VAR_NAME = "GX_CORS_ALLOW_ORIGIN";
7+
private static String CORS_MAX_AGE_SECONDS = "86400";
8+
private static String CORS_ALLOWED_METHODS = "GET, POST, PUT, DELETE, HEAD";
9+
private static String CORS_ALLOWED_HEADERS = "*";
10+
11+
public static HashMap<String, String> getCORSHeaders(String requestRequiredHeaders) {
12+
String corsAllowedOrigin = System.getenv(CORS_ALLOWED_ORIGINS_ENV_VAR_NAME);
13+
if (corsAllowedOrigin == null || corsAllowedOrigin.isEmpty()) {
14+
return null;
15+
}
16+
HashMap<String, String> corsHeaders = new HashMap<>();
17+
corsHeaders.put(
18+
"Access-Control-Allow-Origin", corsAllowedOrigin);
19+
corsHeaders.put(
20+
"Access-Control-Allow-Credentials", "true");
21+
22+
corsHeaders.put(
23+
"Access-Control-Allow-Headers",
24+
requestRequiredHeaders == null || requestRequiredHeaders.isEmpty() ? CORS_ALLOWED_HEADERS : requestRequiredHeaders);
25+
26+
corsHeaders.put(
27+
"Access-Control-Allow-Methods",
28+
CORS_ALLOWED_METHODS);
29+
corsHeaders.put(
30+
"Access-Control-Max-Age",
31+
CORS_MAX_AGE_SECONDS);
32+
return corsHeaders;
33+
}
34+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.genexus.servlet;
2+
3+
4+
import com.genexus.cors.CORSHelper;
5+
import jakarta.servlet.*;
6+
import jakarta.servlet.Filter;
7+
import jakarta.servlet.FilterChain;
8+
import jakarta.servlet.ServletException;
9+
import jakarta.servlet.ServletRequest;
10+
import jakarta.servlet.ServletResponse;
11+
import jakarta.servlet.http.HttpServletRequest;
12+
import jakarta.servlet.http.HttpServletResponse;
13+
14+
import java.io.IOException;
15+
import java.util.HashMap;
16+
17+
public class CorsFilter implements jakarta.servlet.Filter {
18+
19+
@Override
20+
public void init(FilterConfig filterConfig) throws ServletException {
21+
22+
}
23+
24+
@Override
25+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
26+
HttpServletRequest request = (HttpServletRequest) servletRequest;
27+
28+
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers"));
29+
if (corsHeaders != null) {
30+
HttpServletResponse response = (HttpServletResponse) servletResponse;
31+
for (String headerName : corsHeaders.keySet()) {
32+
if (!response.containsHeader(headerName)) {
33+
response.setHeader(headerName, corsHeaders.get(headerName));
34+
}
35+
}
36+
}
37+
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
38+
filterChain.doFilter(servletRequest, servletResponse);
39+
}
40+
}
41+
42+
@Override
43+
public void destroy() {
44+
45+
}
46+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.genexus.ws;
2+
3+
import com.genexus.cors.CORSHelper;
4+
import jakarta.ws.rs.container.ContainerRequestContext;
5+
import jakarta.ws.rs.container.ContainerResponseContext;
6+
import jakarta.ws.rs.container.ContainerResponseFilter;
7+
import jakarta.ws.rs.ext.Provider;
8+
9+
import java.util.Collections;
10+
import java.util.HashMap;
11+
12+
@Provider
13+
public class JAXRSCorsFilter implements ContainerResponseFilter {
14+
@Override
15+
public void filter(ContainerRequestContext requestContext,
16+
ContainerResponseContext responseContext) {
17+
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers"));
18+
if (corsHeaders == null) {
19+
return;
20+
}
21+
for (String headerName : corsHeaders.keySet()) {
22+
responseContext.getHeaders().putSingle(headerName,corsHeaders.get(headerName));
23+
}
24+
}
25+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.genexus.servlet;
2+
3+
import com.genexus.cors.CORSHelper;
4+
5+
import javax.servlet.Filter;
6+
import javax.servlet.FilterChain;
7+
import javax.servlet.FilterConfig;
8+
import javax.servlet.ServletException;
9+
import javax.servlet.ServletRequest;
10+
import javax.servlet.ServletResponse;
11+
import javax.servlet.http.HttpServletRequest;
12+
import javax.servlet.http.HttpServletResponse;
13+
import java.io.IOException;
14+
import java.util.HashMap;
15+
16+
public class CorsFilter implements Filter {
17+
@Override
18+
public void init(FilterConfig filterConfig) throws ServletException {
19+
20+
}
21+
22+
@Override
23+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
24+
HttpServletRequest request = (HttpServletRequest) servletRequest;
25+
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers"));
26+
if (corsHeaders != null) {
27+
HttpServletResponse response = (HttpServletResponse) servletResponse;
28+
for (String headerName : corsHeaders.keySet()) {
29+
if (!response.containsHeader(headerName)) {
30+
response.setHeader(headerName, corsHeaders.get(headerName));
31+
}
32+
}
33+
}
34+
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
35+
filterChain.doFilter(servletRequest, servletResponse);
36+
}
37+
}
38+
39+
@Override
40+
public void destroy() {
41+
42+
}
43+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.genexus.ws;
2+
3+
import com.genexus.cors.CORSHelper;
4+
5+
import javax.ws.rs.container.ContainerRequestContext;
6+
import javax.ws.rs.container.ContainerResponseContext;
7+
import javax.ws.rs.container.ContainerResponseFilter;
8+
import javax.ws.rs.ext.Provider;
9+
import java.util.Collections;
10+
import java.util.HashMap;
11+
12+
@Provider
13+
public class JAXRSCorsFilter implements ContainerResponseFilter {
14+
15+
@Override
16+
public void filter(ContainerRequestContext requestContext,
17+
ContainerResponseContext responseContext) {
18+
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers"));
19+
if (corsHeaders == null) {
20+
return;
21+
}
22+
for (String headerName : corsHeaders.keySet()) {
23+
responseContext.getHeaders().putSingle(headerName,corsHeaders.get(headerName));
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)