留言板

Auth Token for ajax calls (prevent CSRF)

H Meyer,修改在9 年前。

Auth Token for ajax calls (prevent CSRF)

New Member 帖子: 5 加入日期: 14-3-3 最近的帖子
Hi,
i found this topic about the authentication token for "normal" request (with page reload):
https://www.liferay.com/en/community/wiki/-/wiki/Main/Authentication+Token

Can this also be configured for ajax calls?
Init of the serveResource URL:
var globalResourceUrl = '<%= ajaxValidateURL.toString() %>';


a possible ajax call:
		
$.ajax({type: "POST",
   url: globalResourceUrl,
   data: { cmd: "validateURL", feedURL : urlValue}
}).done(function( data ) {
...
}

I checked the ajax url and there was no p_auth or p_p_auth parameter in the url. But I also checked a "normal" request (with page reload), there was automatically a p_p_auth token in the URL.
Do I have to code this on my own? Have anybody some suggestions / URLs to help me?

Thanks in advance.
thumbnail
Tomas Polesovsky,修改在9 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi,

I checked the ajax url and there was no p_auth or p_p_auth parameter in the url. But I also checked a "normal" request (with page reload), there was automatically a p_p_auth token in the URL.

The token you see (p_p_auth) is a different one.

Can this also be configured for ajax calls?
Init of the serveResource URL:


Resource serving requests are not checked for CSRF token currently and there is no portal-wide configuration for it.

You can implement the check by yourself, example:

public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
	HttpServletRequest request = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));

	try {
		// Liferay 6.2:
		AuthTokenUtil.checkCSRFToken(request, this.getClass().getName());
		// Liferay 6.1:
		// AuthTokenUtil.check(request);
	} catch (Exception e) {
		throw new PortletException("Invalid CSRF token!", e);
	}

	//... your code continues here
}


With this check you need to add the p_auth into the Ajax call, for example:
$.ajax({type: "POST",
   url: globalResourceUrl,
   data: {
      cmd: "validateURL", 
      feedURL : urlValue, 
      p_auth: Liferay.authToken
   }
}).done(function( data ) {
...
}


HTH
H Meyer,修改在9 年前。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 帖子: 5 加入日期: 14-3-3 最近的帖子
Thanks for your help, but it is still not working. Sorry for the missing details, we are using liferay 6.1 enterprise edition.
I tried your code and get the following error:
com.liferay.portal.security.auth.PrincipalException: Invalid authentication token
	at com.liferay.portal.security.auth.SessionAuthToken.check(SessionAuthToken.java:61)
	at com.liferay.portal.security.auth.AuthTokenWrapper.check(AuthTokenWrapper.java:32)
	at com.liferay.portal.security.auth.AuthTokenUtil.check(AuthTokenUtil.java:30)
	at com.volkswagenag.mod.carnet.news.action.NewsPortlet.serveResource(NewsPortlet.java:77)
	at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:118)
	at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:71)
	at com.liferay.portal.kernel.servlet.PortletServlet.service(PortletServlet.java:111)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)...


We found out that after this method call PortalUtil.getHttpServletRequest(req) the token id is still correct. But after we call PortalUtil.getOriginalServletRequest(..) the token id will change. And then in the class SessionAuthToken.java in the check method the requestAuthenticationToken and sessionAuthenticationToken are different. And then the error will be thrown.

if i try
AuthTokenUtil.check(PortalUtil.getHttpServletRequest(req));
the requestAuthenticationToken in the check method of SessionAuthToken is then empty / null

Can you help me also with this? Thanks
thumbnail
Tomas Polesovsky,修改在9 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
OK, this was harder than I thought.

Can you please try this workaround?

try {
	HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(PortalUtil.getHttpServletRequest(resourceRequest)){
		@Override
		public String getParameter(String name) {
			if (name.equals("p_auth")) {
				return PortalUtil.getOriginalServletRequest((HttpServletRequest) super.getRequest()).getParameter(name);
			}

			return super.getParameter(name);
		}
	};
	AuthTokenUtil.check(wrapper);
} catch (Exception e) {
	throw new PortletException("Invalid CSRF token!", e);
}
H Meyer,修改在9 年前。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 帖子: 5 加入日期: 14-3-3 最近的帖子
Thanks this is working.

So can i consider this as a bug from liferay?
thumbnail
Tomas Polesovsky,修改在9 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
It seems it wasn't designed to work from inside of the plugin.

On the other hand, the functionality has public interface, I'd say it's part of public API, but current implementation doesn't support use from plugins.

I think it could be a bug.
Ngocha Haobam,修改在8 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 帖子: 87 加入日期: 15-1-30 最近的帖子
Can you please tell me, where did you define ---> Liferay.authToken
Artur Karwowski,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 发布: 1 加入日期: 15-7-16 最近的帖子
Hi Tomas,

Recenty I implemented a CSRF token check using an interceptor for ajax calls to the Spring DispacherServlet via PortalDelegateServlet.

github link

Could something similar be implemented for CSRF checks for Resource calls to DispacherPortlet?

Thanks,
Artur
thumbnail
Tomas Polesovsky,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi Artur,

thanks for the idea, but in general we cannot implement that.

Resource requests are like double-edge sword. They can serve static content but also change server state.

-> When developers serve static content there must be no CSRF token so that browser/proxy can cache the content.

-> But when developers use it in AJAX calls to change server state they must check CSRF token.

When portal framework decides to omit CSRF check or on the other hand force CSRF check it always fail one of the scenarios above, there is no win.

So the default behaviour is aligned with portlet spec which doesn't enforce any such check.

Btw. can you please spawn a new thread next time instead of poisoning this one? If you mention my name I'll see it. Thanks!
thumbnail
Arunjyoti Banik,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 帖子: 74 加入日期: 14-8-26 最近的帖子
Great information Tomas. Thanks emoticon
gvs cbe,修改在4 年前。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 帖子: 6 加入日期: 19-5-26 最近的帖子
Exception as com.liferay.portal.security.auth.PrincipalException$Mustbeauthenticated: in Liferay 7.0 Community Edition
Please advice on this
Ngocha Haobam,修改在8 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 帖子: 87 加入日期: 15-1-30 最近的帖子
Can you please tell me, where did you define ---> Liferay.authToken
thumbnail
Tomas Polesovsky,修改在8 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Ngocha Haobam:
Can you please tell me, where did you define ---> Liferay.authToken


Hi,

Liferay.authToken is defined by Liferay in top_js.jspf
thumbnail
Arunjyoti Banik,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 帖子: 74 加入日期: 14-8-26 最近的帖子
Tomas Polesovsky:
Ngocha Haobam:
Can you please tell me, where did you define ---> Liferay.authToken


Hi,

Liferay.authToken is defined by Liferay in top_js.jspf


Hi Tomas,

A little more information I need. Liferay, by default, adds the p_auth token to only Action Requests across the whole portal. Can you tell me where, that means which Java file it is defined, that the auth token will be appended only to the action requests??

Regards
Arun
thumbnail
Tomas Polesovsky,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi,it should be PortletUrlImpl
thumbnail
Arunjyoti Banik,修改在7 年前。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 帖子: 74 加入日期: 14-8-26 最近的帖子
Thanks Tomas. emoticon