44

I had a static website hosted by Tomcat.

How to set a header for my site like:Access-Control-Allow-Origin: *

They are all static file, not any servlet application.

Braiam
  • 1
  • 11
  • 47
  • 78
Dozer
  • 5,025
  • 11
  • 36
  • 52
  • Does this answer your question? [Access-Control-Allow-Origin: \* in tomcat](https://stackoverflow.com/questions/12383109/access-control-allow-origin-in-tomcat) – Josh Correia Feb 11 '21 at 21:05

4 Answers4

78

If it's a static site, then starting with Tomcat 7.0.41, you can easily control CORS behavior via a built-in filter.

References:

Pretty much the only thing you have to do is edit the global web.xml in CATALINA_HOME/conf and add the filter definition:

     <!-- ================== Built In Filter Definitions ===================== -->

      ...

     <filter>
       <filter-name>CorsFilter</filter-name>
       <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
     </filter>
     <filter-mapping>
       <filter-name>CorsFilter</filter-name>
       <url-pattern>/*</url-pattern>
     </filter-mapping>

    <!-- ==================== Built In Filter Mappings ====================== -->

Be aware, though, that Firefox does not like Access-Control-Allow-Origin: * and requests with credentials (cookies): when responding to a credentialed request, server must specify a domain, and cannot use wild carding.

If you want to debugs requests in this situation, please be aware that CORS headers are only sent if there is a cross-origin request according to this flow-chart. CORS flow chart

(tomcat.apache.org/tomcat-8.0-doc/images/cors-flowchart.png)

Johannes Jander
  • 4,974
  • 2
  • 31
  • 46
  • 5
    When one debugs that, please be aware that CORS headers are only sent if there is a cross-origin request. See https://tomcat.apache.org/tomcat-8.0-doc/images/cors-flowchart.png. So please do not just inspect random calls (using Fiddler, network tab, ...), but really the CORS requests themselves. – koppor Nov 23 '16 at 11:37
  • 2
    After adding that filter I am still getting *Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 403*. Also my method which is actually a GET has been converted into OPTION and returns 403 – Jerry Jan 03 '18 at 13:46
  • 3
    There is this [nice site](http://test-cors.org) that lets you send CORS requests, if you want to test something. – rrrocky Jul 30 '18 at 09:47
  • Note t hat this does not actually add the header unless you also set cors.allowed.origins. Other parameters have usable defaults but you definitely need to set this one as well. (It's not actually working for me but the docs are very clear on this so maybe this might help somebody...) – tekHedd Dec 19 '18 at 00:40
  • @Johannes will this not work if we have the filter in application web.xml? – Prajwal Jan 04 '19 at 07:11
  • @prajwal I didn't try, but I doubt it, since it is a setting that influences more than one application deployed on the tomcat – Johannes Jander Jan 05 '19 at 21:30
  • @rockydgeekgod thanks for the link to test-cors.org, that gave me the code that I needed - you're a hero! – Guy Starbuck Apr 05 '19 at 20:19
  • 1
    You can set the allowed origins like this: ``` CorsFilter org.apache.catalina.filters.CorsFilter cors.allowed.origins * ``` – Simon Zyx Oct 08 '19 at 13:23
  • Also more advanced options can be found here: https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter – Simon Zyx Oct 08 '19 at 13:24
14

Here is a very basic filter that will add the CORS headers. Note that by default, this will enable all domains and methods so you should customize it to fit your needs.

It also needs to be the first filter in your web.xml.

package com.conductiv.api.listener;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CORSFilter implements Filter {
    public void destroy() {
    }
    public static String VALID_METHODS = "DELETE, HEAD, GET, OPTIONS, POST, PUT";

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        HttpServletResponse httpResp = (HttpServletResponse) resp;

        // No Origin header present means this is not a cross-domain request
        String origin = httpReq.getHeader("Origin");
         if (origin == null) {
            // Return standard response if OPTIONS request w/o Origin header
           if ("OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
                httpResp.setHeader("Allow", VALID_METHODS);
                httpResp.setStatus(200);
                return;
            }
        } else {
            // This is a cross-domain request, add headers allowing access
            httpResp.setHeader("Access-Control-Allow-Origin", origin);
            httpResp.setHeader("Access-Control-Allow-Methods", VALID_METHODS);

            String headers = httpReq.getHeader("Access-Control-Request-Headers");
            if (headers != null)
                httpResp.setHeader("Access-Control-Allow-Headers", headers);

            // Allow caching cross-domain permission
            httpResp.setHeader("Access-Control-Max-Age", "3600");
        }
        // Pass request down the chain, except for OPTIONS
        if (!"OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
            chain.doFilter(req, resp);
        }
 }

    public void init(FilterConfig config) throws ServletException {

    }

}
Federico Raggi
  • 637
  • 4
  • 6
11

Please note, that to configure CORS filter with value *, except enabling the filer you also need to add <param-value>*</param-value> configuration for parameter <param-name>cors.allowed.origins</param-name> as follows (building on top of Johannes Jander answer):

 <!-- ================== Built In Filter Definitions ===================== -->

  ...

 <filter>
   <filter-name>CorsFilter</filter-name>
   <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
   <init-param>
     <param-name>cors.allowed.origins</param-name>
     <param-value>*</param-value>
   </init-param>
 </filter>
 <filter-mapping>
   <filter-name>CorsFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

<!-- ==================== Built In Filter Mappings ====================== -->
mimo
  • 6,221
  • 7
  • 42
  • 50
3

You need to add a Filter to add the additional header and configure it to all paths

<filter>
  <filter-name>header</filter-name>
  <filter-class>...</filter-class>
</filter>
<filter-mapping>
  <filter-name>header</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
shyam
  • 9,134
  • 4
  • 29
  • 44