留言板
Auth Token for ajax calls (prevent CSRF)
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:
a possible ajax call:
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.
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.
Tomas Polesovsky,修改在9 年前。
RE: Auth Token for ajax calls (prevent CSRF)
Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi,
The token you see (p_p_auth) is a different one.
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:
With this check you need to add the p_auth into the Ajax call, for example:
HTH
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
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:
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
Can you help me also with this? Thanks
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 / nullCan you help me also with this? Thanks
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?
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);
}
Thanks this is working.
So can i consider this as a bug from liferay?
So can i consider this as a bug from liferay?
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.
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
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
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!
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!
Arunjyoti Banik,修改在7 年前。
RE: Auth Token for ajax calls (prevent CSRF)
Junior Member 帖子: 74 加入日期: 14-8-26 最近的帖子
Great information Tomas. Thanks
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
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
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
Tomas Polesovsky,修改在7 年前。
RE: Auth Token for ajax calls (prevent CSRF)
Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi,it should be PortletUrlImpl
Arunjyoti Banik,修改在7 年前。
RE: Auth Token for ajax calls (prevent CSRF)
Junior Member 帖子: 74 加入日期: 14-8-26 最近的帖子
Thanks Tomas.