CAMD_3441
CAMD_3441

Reputation: 3154

Enable CORS settings in Payara (or Glassfish) server

Does anyone know how to enable CORS for certain domains in the Payara server directly (or glassfish)?

I'm working with Payara server 4.1.1.171.1.

I have an app running on localhost:3000 that needs to talk to the Payara server but I keep getting a CORS error.

Most links I found say simply to add the domain (ie localhost) to the response header, as such:

response.addHeader("Access-Control-Allow-Origin", "localhost");

and i have done that in my java code and it works. But I want to know how to update Payara(or glassfish) in the server directly to do that. Because I've seen people make suggestions to do just that (ie update a server config file to allow CORS for certain domains). That way the java codewouldn't have to specifically add the header content above.

But those suggestions had examples for servers that are not Glassfish nor Payara.

Even this CORS link https://enable-cors.org/server.html lists out 20 or so servers/platforms on how to enable CORS but none are Payara or Glassfish.

Does anyone know how to do so?

Thanks in advance!

Upvotes: 3

Views: 4320

Answers (2)

rieckpil
rieckpil

Reputation: 12021

For a more open cors filtering, you can use the following:

import java.io.IOException;
import java.util.List;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;


@Provider
public class CorsResponseFilter implements ContainerResponseFilter {

    public static final String ALLOWED_METHODS = "GET, POST, PUT, DELETE, OPTIONS, HEAD";
    public final static int MAX_AGE = 42 * 60 * 60;
    public final static String DEFAULT_ALLOWED_HEADERS = "origin,accept,content-type";
    public final static String DEFAULT_EXPOSED_HEADERS = "location,info";

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        final MultivaluedMap<String, Object> headers = responseContext.getHeaders();
        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", getRequestedAllowedHeaders(requestContext));
        headers.add("Access-Control-Expose-Headers", getRequestedExposedHeaders(requestContext));
        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
        headers.add("Access-Control-Max-Age", MAX_AGE);
        headers.add("x-responded-by", "cors-response-filter");
    }

    String getRequestedAllowedHeaders(ContainerRequestContext responseContext) {
        List<String> headers = responseContext.getHeaders().get("Access-Control-Allow-Headers");
        return createHeaderList(headers, DEFAULT_ALLOWED_HEADERS);
    }

    String getRequestedExposedHeaders(ContainerRequestContext responseContext) {
        List<String> headers = responseContext.getHeaders().get("Access-Control-Expose-Headers");
        return createHeaderList(headers, DEFAULT_EXPOSED_HEADERS);
    }

    String createHeaderList(List<String> headers, String defaultHeaders) {
        if (headers == null || headers.isEmpty()) {
            return defaultHeaders;
        }
        StringBuilder retVal = new StringBuilder();
        for (int i = 0; i < headers.size(); i++) {
            String header = (String) headers.get(i);
            retVal.append(header);
            retVal.append(',');
        }
        retVal.append(defaultHeaders);
        return retVal.toString();
    }

}

From Adam Bien's cors project on GitHub

Upvotes: 1

Sorin Penteleiciuc
Sorin Penteleiciuc

Reputation: 865

You need to create an interceptor for each call where you must add more headers to it. On some conditions which you need. Please take a look at the code below :

import javax.ws.rs.HttpMethod;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;


@Provider
@PreMatching
public class CorsResponseFilter implements ContainerResponseFilter {

public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
            String origin = requestContext.getHeaderString("Origin");
            if ((origin != null) 
                    && origin.startsWith("http://localhost:4200") || origin.startsWith("http://localhost:8080"))) {
                allowExceptionCors(requestContext, responseContext, origin);
            } 
    }

    private void allowExceptionCors(ContainerRequestContext requestContext, ContainerResponseContext responseContext, String origin) {
        String methodHeader = requestContext.getHeaderString("Access-Control-Request-Method");
        String requestHeaders = requestContext.getHeaderString("Access-Control-Request-Headers");

        MultivaluedMap<String, Object> headers = responseContext.getHeaders();
        headers.putSingle("Access-Control-Allow-Origin", origin);
        headers.putSingle("Access-Control-Allow-Credentials", "true");
        headers.putSingle("Access-Control-Allow-Methods", methodHeader);
        headers.putSingle("Access-Control-Allow-Headers", "x-requested-with," + (requestHeaders == null ? "" : requestHeaders));
    }
}

Upvotes: 1

Related Questions