Search code examples
tomcatdockercorscamunda

CORS error when accessing Tomcat inside docker container


I am building an Angular 4 app which interacts with Camunda process using REST APIs. Trying to login, facing CORS error.

Dockerfile:

FROM camunda/camunda-bpm-platform:tomcat-latest

ADD sample.war /camunda/webapps/sample.war

COPY ./web.xml /camunda/webapps/engine-rest/WEB-INF

Running it like:

docker build -t camunda-eval .
docker run -d --name camunda -p 8080:8080 <image>

Error in the console:

Failed to load http://localhost:8080/camunda/api/admin/auth/user/default/login/tasklist: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

My web.xml looks like this:

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <filter>
    <filter-name>EmptyBodyFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.EmptyBodyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>EmptyBodyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter>
    <filter-name>CacheControlFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.CacheControlFilter</filter-class>    
  </filter>
  <filter-mapping>
    <filter-name>CacheControlFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- Http Basic Authentication Filter -->
  <!-- <filter>
    <filter-name>camunda-auth</filter-name>
    <filter-class>
      org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter
    </filter-class>
    <init-param>
      <param-name>authentication-provider</param-name>
      <param-value>org.camunda.bpm.engine.rest.security.auth.impl.HttpBasicAuthenticationProvider</param-value>
    </init-param>
    <init-param>
        <param-name>rest-url-pattern-prefix</param-name>
        <param-value></param-value>
      </init-param> 
  </filter>

  <filter-mapping>
    <filter-name>camunda-auth</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping> -->

  <filter>
      <filter-name>Resteasy</filter-name>
      <filter-class>
          org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
      </filter-class>
      <init-param>
          <param-name>javax.ws.rs.Application</param-name>
          <param-value>org.camunda.bpm.engine.rest.impl.application.DefaultApplication</param-value>
      </init-param>
  </filter>

  <filter-mapping>
      <filter-name>Resteasy</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
 <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>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>
  <filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

Any ideas on how to fix this?


Solution

  • You are getting this error because "localhost:4200" and "localhost:8080" are not the same machine when it comes to CORS.

    In general, you have 3 ways to avoid this:

    1. just tell your browser to ignore CORS (for example chromium-browser --disable-web-security --user-data-dir) - this is the fastest if you just want to play around, but of course no production solution
    2. set CORS headers on 8080 to allow access from 4200 ... not applicable here (easily, since you do not control the camunda-app)
    3. use an "edge" (or "gateway") server that internally re-routes requests via reverse-proxying. Meaning: your browser only talks to the gateway (lets say port 80) and this routes requests either to your tasklist (4200) or camunda (8080). This is the standard way to solve this and you will find good documentation if you look for nginx or zuul. It will require an additional service component, though.