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:
ADF CORS solving strategies
enable-cors-in-alfresco-and-how-to-use.html
Enabling CORS on Alfresco ECM
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.
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.
I have this configuration in my application.yml
server:
contextPath: /appname
session:
timeout: 7200 # 2 hours in seconds
This works fine when i run in Intellij IDEA, but when i deploy the build .war file to a tomcat instance this is ignored. Is this a bug or is it not expected to work like this?
Also i seem to be unable to locate a specification of what can be written in application.yml. Anyone know where this can be found?
How about the application.groovy config file? Cant seem to locate a specification for this?
My environment:
Grails version: 3.2.8
Gradle version: 3.4.1
Intellij IDEA version: 2017.1.2
Tomcat version: 8.0.26
JDK Version: 1.8.0_45
When you deploy a Grails 3 app to a standalone tomcat application you should not use springboot server.session.timeout configuration property. That it is only for an embeedded server.
To configure a session timeout in a SpringBoot app (Grails 3 app is built on top of SpringBoot app) deployed into a standalone tomcat you have two choices:
A) Timeout for every app deployed in that tomcat instance.
You could edit the session timeout directly in tomcat configuration files:
$TOMCAT_HOME/conf/web.xml
Look out for the block:
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
B) You can add a web.xml file in your Grails 3 app, with the timeout you need per app.
Create a file in the path 'src/main/webapp/WEB-INF/web.xml' with the content:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
C) You can also use tomcat's HttpSession setMaxInactiveInterval(seconds) method to set in your Groovy code.
if (grailsApplication.config.getProperty("session.timeout")?.isInteger())
// session timeout in seconds
session.setMaxInactiveInterval(grailsApplication.config.session.timeout as int)
Note that with the (current latest) Grails 5.x and spring boot 2.5 the correct property name is server.servlet.session.timeout and hence the application.yml config would go like this:
server:
servlet:
session:
timeout: 3600 #seconds
Spring boot docs:
https://docs.spring.io/spring-boot/docs/2.5.5/reference/html/application-properties.html#application-properties.server.server.servlet.session.timeout
Wildfly 8, Omnifaces 2.2, Primefaces 5.2, JSF 2.2.11 (Mojarra)
I am using Ominifaces CharacterEncodingFilter to ensure that file names are encoded correctly on server. Oddly if Primefaces using Jsf internal upload, the file name are not encoded. And if Primefaces use older approach with Appache Commons it is ok.
Example: 'Hällo.jpg' becomes 'Hällo.jpg'
Web.xml configurations:
Apache solution (correct):
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.omnifaces.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Jsf Upload (characters are not encoded). Other parameters are removed.
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.omnifaces.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
EDIT: due to answer this is a server bug. I've tried to configure the server:
<jboss-web>
<default-encoding>UTF-8</default-encoding>
</jboss-web>
and
<servlet-container name="default" default-encoding="UTF-8">
but it doesn't help.
I reproduced it, WildFly isn't at all considering request request body encoding for multipart/form-data requests. You really have to configure it in server end (like as you would do for GET requests).
Open /standalone/configuration/standalone.xml, peek the following line
<servlet-container name="default">
change it to
<servlet-container name="default" default-encoding="UTF-8">
and restart. This at least worked for me on WildFly 10.0.0. I created issue WFLY-6226 to let it consider request body encoding first so there's no need to edit standalone.xml on that.
In WildFly 8.x (I tested 8.2.1) this unfortunately still won't work as it does not at all consider the above setting. Your best bet is to keep using Apache Commons FileUpload until you can upgrade WildFly.
If you really want to keep native upload, then you could consider to explicitly decode the broken filename to bytes using ISO-8859-1 and then re-encode it using UTF-8.
String fileName = new String(uploadedFile.getFileName().getBytes("ISO-8859-1"), "UTF-8");
This is however brittle and not portable as it would break when deployed to a server where this encoding problem doesn't manifest. So you really need to remember to revert the workaround when upgrading/migrating.
I am trying to add JavaMelody monitoring to a Rails 4.0 app which we deploy to Tomcat running on Windows 2008 R2, with the help of JRuby and Warbler. As described in the JavaMelody user guide, I have added both javamelody.jar and jrobin-1.5.9.jar to WEB-INF/lib/ and extended our web.xml too look essentially like this:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- JavaMelody -->
<filter>
<filter-name>monitoring</filter-name>
<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
<init-param>
<param-name>log</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>monitoring</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>net.bull.javamelody.SessionListener</listener-class>
</listener>
<!-- JRuby-Rack-->
<filter>
<filter-name>RackFilter</filter-name>
<filter-class>org.jruby.rack.RackFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RackFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.jruby.rack.rails.RailsServletContextListener</listener-class>
</listener>
</web-app>
This seems to work to some extend - there seems to be monitoring information recorded, as I can see that a folder <TOMCAT_HOME>\temp\javamelody is created, and the files therein seem to be updated which each request I make to the app.
But unfortunately, what doesn't work is actually opening the monitoring report. When I go to http://localhost:8080/ourapp/monitoring, I don't get a report page as described in the user guide, but the 404 page of our Rails app instead. The Tomcat logs confirm that both the JavaMelody monitoring filter and SessionListener have been loaded and don't seem to reveal any errors. What have I missed?
since you mapped JRuby-Rack to handle everything (/*) you either need to re-arrange the mapping to make sure the specific path(s) take precedence in being handled by the other filter e.g.
<filter-mapping>
<filter-name>monitoring</filter-name>
<url-pattern>/monitoring</url-pattern>
</filter-mapping>
or alternatively not route everything to JRuby-Rack if the paths it needs to handle can be mapped (you might need to change the monitoring filter paths as well or try using the RackServlet instead if you do not mind "replacing" the container default servel)
I am using the new Servlet 3.0 approach of packaging web resources (such as Javascript, CSS, and JSPs) in JAR files. The approach says that everything under JARROOT/src/META-INF/resources will get mounted to the WAR root when the application starts. All works file for CSS and Javascript but not so much for Struts tiles.
This is the structure I have in the JAR:
base.jar
|--src/
|----META-INF/
|------base.tld
|------resources/
|--------base/
|----------css/
|----------js/
|----------baseTiles.xml
In my application (WAR) web.xml I got this for the tiles:
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles.xml,/base/baseTiles.xml</param-value>
</context-param>
When I start my application I do not get any errors about the baseTiles.xml so I assume it would the tiles files. However, trying to reference a tile from a JSP (using the <tiles:insertAttribute> tag) fails with
org.apache.tiles.jsp.taglib.NoSuchAttributeException: Attribute 'base.nav' not found.
What do you think the is?
Summary and other info:
Using JBoss eap 6.1 Alpha
Using Struts 2.1.4
The base JAR is included with the WAR in the lib directory
The base JAR contain all the files mentioned above (including baseTiles.xml)
Thank you for your help!!
Problem solved! Must point to the right Schema in your web.xml...
<web-app version="3.1" 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://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/web-app_3_1.xsd">
Now everything works automagically !!
It is the right schema definition for 3.1 servlet specification:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">