掲示板

Auth Token for ajax calls (prevent CSRF)

9年前 に H Meyer によって更新されました。

Auth Token for ajax calls (prevent CSRF)

New Member 投稿: 5 参加年月日: 14/03/03 最新の投稿
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
9年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/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
9年前 に H Meyer によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 投稿: 5 参加年月日: 14/03/03 最新の投稿
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
9年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/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);
}
9年前 に H Meyer によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 投稿: 5 参加年月日: 14/03/03 最新の投稿
Thanks this is working.

So can i consider this as a bug from liferay?
thumbnail
9年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/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.
8年前 に Ngocha Haobam によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 投稿: 87 参加年月日: 15/01/30 最新の投稿
Can you please tell me, where did you define ---> Liferay.authToken
7年前 に Artur Karwowski によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 投稿: 1 参加年月日: 15/07/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
7年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/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
7年前 に Arunjyoti Banik によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 投稿: 74 参加年月日: 14/08/26 最新の投稿
Great information Tomas. Thanks emoticon
4年前 に gvs cbe によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

New Member 投稿: 6 参加年月日: 19/05/26 最新の投稿
Exception as com.liferay.portal.security.auth.PrincipalException$Mustbeauthenticated: in Liferay 7.0 Community Edition
Please advice on this
8年前 に Ngocha Haobam によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 投稿: 87 参加年月日: 15/01/30 最新の投稿
Can you please tell me, where did you define ---> Liferay.authToken
thumbnail
8年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/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
7年前 に Arunjyoti Banik によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 投稿: 74 参加年月日: 14/08/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
7年前 に Tomas Polesovsky によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Liferay Master 投稿: 676 参加年月日: 09/02/13 最新の投稿
Hi,it should be PortletUrlImpl
thumbnail
7年前 に Arunjyoti Banik によって更新されました。

RE: Auth Token for ajax calls (prevent CSRF)

Junior Member 投稿: 74 参加年月日: 14/08/26 最新の投稿
Thanks Tomas. emoticon