Issue
- When attempting to access the
/languageURL (e.g., http://localhost:8080/language), it shows a 403 Forbidden error even if the language page doesn't exist:
In the logs, this error is observed:
ERROR [WebContainer : 19][LanguageServlet:64] Invalid authentication token received com.liferay.portal.kernel.security.auth.PrincipalException$MustHaveValidCSRFToken: User 0 did not provide a valid CSRF token for com.liferay.portal.servlet.LanguageServlet
Environment
- Liferay DXP 7.3+
Resolution
The CSRF token check is enabled for all origins that are not whitelisted in this auth.token.ignore.origins portal property:
# Set a list of comma delimited origins that will not be checked for an
# authentication token.
#
# Env: LIFERAY_AUTH_PERIOD_TOKEN_PERIOD_IGNORE_PERIOD_ORIGINS
#
# auth.token.ignore.origins=\
# com.liferay.portal.action.JSONServiceAction:com.liferay.portlet.expando.service.ExpandoValueServiceUtil#getJSONData,\
# com.liferay.portal.action.LoginAction,\
# com.liferay.portal.action.UpdateTermsOfUseAction,\
# com.liferay.portlet.asset.action.GetCategoriesAction,\
# com.liferay.portlet.portletconfiguration.action.GetLookAndFeelActionTo add com.liferay.portal.servlet.LanguageServlet to the whitelist:
- Define the
auth.token.ignore.originsproperty within yourportal-ext.properties - Include
com.liferay.portal.servlet.LanguageServletwithin the list of values you'd like to whitelist.- If your
portal-ext.propertiesfile already setsauth.token.ignore.origins, add this to the existing comma-separated list instead
- If your
Additional Information
- This setting turns off CSRF token validation for the Language Servlet; however, the servlet only reads the translation of the language key in the URL (
/language/<languageId>/<key>) and returns it as plain text. This doesn't return a 404 unless the key itself doesn't exist. - The
/language/*path is mapped to the location of the Language Servlet (e.g.,bundle-root/tomcat-x.x.xx/webapps/ROOT/WEB-INF/web.xml):
<servlet>
<servlet-name>Language Servlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.LanguageServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
...
<servlet-mapping>
<servlet-name>Language Servlet</servlet-name>
<url-pattern>/language/*</url-pattern>
</servlet-mapping>