dockercorsalfrescoalfresco-webscripts

Dockerized Alfresco CORS filter


I have a dockerized Alfresco 6.2 community version, clean for now, up and running correctly in my AWS server. I can use it ang log in into share.

Now I want to add my custom app, writtein in Vue.js, which is dockerized too, and make calls to the Alfresco REST APIs to develop my customizations. When I call any of the APIs I always receive CORS error.

I've tryied many many times, changing Alfresco configuration, Tomcat server configuration, using jar and so on, but nothing has changed.

The error I get is always Access to XMLHttpRequest at 'http://my-alfresco-url/alfresco/api/-default-/public/authentication/versions/1/tickets' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here is my simplified API call (just for simplicity, the fetch method I use inside my Vue.js app is the same)

    <!DOCTYPE html>
    <html>

    <head>
        <meta charset='utf-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>Page Title</title>
        <meta name='viewport' content='width=device-width, initial-scale=1'>
    </head>

    <body>

    <script>
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");
        myHeaders.append("Access-Control-Allow-Origin", "*");
        myHeaders.append("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
        myHeaders.append("Access-Control-Allow-Headers","Origin, Content-Type, X-Auth-Token, Access-Control-Allow-Methods, Access-Control-Allow-Origin");

        var raw = JSON.stringify({
            "userId": "user",
            "password": "password"
        });

        var requestOptions = {
            method: 'POST',
            headers: myHeaders,
            body: raw,
            redirect: 'follow',
        };

        fetch("http://my-alfresco-url/alfresco/api/-default-/public/authentication/versions/1/tickets", requestOptions)
            .then(response => response.json())
            .then(result => console.log(result))
            .catch(error => console.log('error', error));
    </script>

    </body>

    </html>

Here is my alfresco-global.properties:

    cors.enabled=true
    cors.allowed.origins=*
    cors.allowed.methods=GET,POST,HEAD,OPTIONS,PUT
    cors.allowed.headers=Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers
    cors.exposed.headers=Access-Control-Allow-Origin,Access-Control-Allow-Credentials
    cors.support.credentials=false
    cors.preflight.maxage=1800

I tried changing those parameters, but it didn't work.

I've tried changing tomcat/conf/web.xml or tomcat/webapps/alfresco/WEB-INF/web.xml adding this section

    <!-- CORS Filter Begin -->
    <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>1800</param-value>
        </init-param>
    </filter><!-- CORS Filter End -->


    <!-- CORS Filter Mappings Begin -->
    <filter-mapping>
        <filter-name>CorsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- CORS Filter Mappings End -->

but if I use it as shown then The entire Alfresco is broken, with errors like

    provacors-ass_1       | 2021-04-19 12:07:10.007 ERROR (org.alfresco.solr.AlfrescoCoreAdminHandler@29a5f4e7_Worker-24) [   ] o.a.s.t.AbstractTracker Tracking failed for AclTracker - archive
    provacors-ass_1       | org.alfresco.error.AlfrescoRuntimeException: 03190007 api/solr/aclchangesets return status:404
    provacors-ass_1       |         at org.alfresco.solr.client.SOLRAPIClient.getAclChangeSets(SOLRAPIClient.java:169)
    provacors-ass_1       |         at org.alfresco.solr.tracker.AclTracker.checkRepoAndIndexConsistency(AclTracker.java:338)
    provacors-ass_1       |         at org.alfresco.solr.tracker.AclTracker.trackRepository(AclTracker.java:303)
    provacors-ass_1       |         at org.alfresco.solr.tracker.AclTracker.doTrack(AclTracker.java:95)
    provacors-ass_1       |         at org.alfresco.solr.tracker.AbstractTracker.track(AbstractTracker.java:215)
    provacors-ass_1       |         at org.alfresco.solr.tracker.TrackerJob.execute(TrackerJob.java:47)
    provacors-ass_1       |         at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
    provacors-ass_1       |         at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:563)

I've followed this question without any result: How to resolve CORS error in alfresco webscripts in alfresco sdk?

I've read this forums without any success:

I also tried using webpack configuration, with Vue, but I'm not so sure I did it correctly. It didn't work.

What am I missing? How is it possible to use a custom javascript call in another domain with Dockerized Alfresco?

Thanks.


Solution

  • After many trials, I've managed to work. Here is how I did.

    First things first, alfresco-global.properties cors options seems to be useless and uneffective. At least for ACS. If there is anyone who can explain me how they work I'll appreciate it.

    I needed to add two libraries to my Alfresco 6.2 tomcat/webapps/WEB-INF/lib folder, cors-filter v2.5 and java-property-utils v. 1.9.1. They has to be exactly those versions (not the newer one 2.10 and 1.16) or they won't work with the next web.xml configuration.

    I added them to my acs/platform pom.xml

    <dependency>
        <groupId>com.thetransactioncompany</groupId>
        <artifactId>cors-filter</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>com.thetransactioncompany</groupId>
        <artifactId>java-property-utils</artifactId>
        <version>1.9.1</version>
    </dependency>
    

    and this is their web.xml configuration, to relax CORS filter:

    
       <!-- CORS Filter Begin -->
       <filter>
          <filter-name>CORS</filter-name>
          <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
          <init-param>
             <param-name>cors.allowGenericHttpRequests</param-name>
             <param-value>true</param-value>
          </init-param>
          <init-param>
             <param-name>cors.allowOrigin</param-name>
             <param-value>*</param-value>
          </init-param>
          <init-param>
             <param-name>cors.allowSubdomains</param-name>
             <param-value>true</param-value>
          </init-param>
          <init-param>
             <param-name>cors.supportedMethods</param-name>
             <param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
          </init-param>
          <init-param>
             <param-name>cors.supportedHeaders</param-name>
             <param-value>origin, authorization, x-file-size, x-file-name, content-type, accept, x-file-type</param-value>
          </init-param>
          <init-param>
             <param-name>cors.supportsCredentials</param-name>
             <param-value>true</param-value>
          </init-param>
          <init-param>
             <param-name>cors.maxAge</param-name>
             <param-value>3600</param-value>
          </init-param>
       </filter>
       <!-- CORS Filter End -->
    
       <!-- CORS Filter Mappings Begin -->
       <filter-mapping>
          <filter-name>CORS</filter-name>
          <url-pattern>/api/*</url-pattern>
          <url-pattern>/service/*</url-pattern>
          <url-pattern>/s/*</url-pattern>
          <url-pattern>/cmisbrowser/*</url-pattern>
       </filter-mapping>
       <!-- CORS Filter Mappings End -->
    

    note the <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> value.

    To add those values I customized my acs-platform-docker project and added next line to Dockerfile instructions:

    # TO ENABLE CORS
    COPY web.xml ${TOMCAT_DIR}/webapps/alfresco/WEB-INF/web.xml
    

    obviusly the modified web.xml file was put inside acs-platform-docker resource folder, it needs to be included when the image is built.

    If there is another way to handle this, please let me know.