XsrfTokenServiceServlet throws RpcTokenException: Invalid RPC token

2,448 views
Skip to first unread message

dhoffer

unread,
Jul 24, 2012, 6:02:45 PM7/24/12
to google-we...@googlegroups.com
I've been switching my RPC calls to use XsrfTokenServiceServlet per this link https://developers.google.com/web-toolkit/articles/security_for_gwt_applications#cross-site

It's working quite well except that I occasionally get this error on the first RPC method call.  

Exception while dispatching incoming RPC call com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract com.google.gwt.user.client.rpc.XsrfToken com.google.gwt.user.client.rpc.XsrfTokenService.getNewXsrfToken()' threw an unexpected exception: com.google.gwt.user.client.rpc.RpcTokenException: Invalid RPC token (Session cookie is not set or empty! Unable to generate XSRF cookie)  

I found one other group message about this but wasn't sure what's the best fix.  The workaround I'm using at the moment is to set this in the client when my app starts:

Random random = new Random();
Cookies.setCookie("JSESSIONID", Long.toString(random.nextLong()));

However this raises a number of questions/problems.
- How to guarantee that JSESSIONID is the right cookie name as the actual name is defined in web.xml.
- Do I have to configure any expiration?  
- Seems like a server solution would be better but I didn't find one that works.

Or is it preferred to just not protect the first RPC method?

How have others solved this?  (Seems like if this is expected to be an issue...GWT would have mentioned it in the link.)

Thanks,
-Dave


alexkrishnan

unread,
Jul 24, 2012, 6:32:25 PM7/24/12
to google-we...@googlegroups.com
I just started implementing the same guide, and used a similar workaround to you:

if (Cookies.getCookie("JSESSIONID") == null) // We must have a session cookie in order to authenticate with the server

    Cookies.setCookie("JSESSIONID", Double.toString(Math.random()));

XsrfTokenServiceAsync xsrf = (XsrfTokenServiceAsync) GWT.create(XsrfTokenService.class);

//etc..


However, this workaround really doesn't sit well with me. Does anyone know what we're missing?

Jens

unread,
Jul 25, 2012, 6:58:57 AM7/25/12
to google-we...@googlegroups.com
The session cookie should always be present because of your login process. You don't need an XSRF token during login but once you have successfully authenticated (and thus a session id is available) the very first thing to do is to fetch a XSRF token from the server. So basically your login() and getNewXsrfToken() methods are not protected with an XSRF token.

Personally I like to have two apps, the first one is just a very small login app (not necessarily a GWT app) that does not use XSRF Tokens at all and the second app is the real GWT app. Once the real app starts the very first thing it does is to fetch an XSRF token and then use it for all other requests, like fetching the logged in user information which would probably the second thing to do. If I can't get an XSRF token for any reason I redirect to the login app.
In this scenario you could also use a dynamic host page for the real app and let the server dynamically include the XSRF token and user information right into the host page so you can read it with GWT using the Dictionary class. That would save some requests on app startup. But personally I don't do that for now.

-- J.

dhoffer

unread,
Jul 25, 2012, 9:45:35 AM7/25/12
to Google Web Toolkit
Thanks Alex & Jens,

I have two separate applications where I'd like to use this approach
to protect against XSRF attacks.

In one of them I'm seeing this problem with GWT in hosted mode so
there is no login process at all. Eventually it will be put inside of
an enterprise ear and will have a login process so given what you say
that will solve the problem...but I still need a solution for hosted
mode so I can develop/test.

In the other app I'm planning to use method level security with Spring
Security (AOP) so in this app there will not be a separate login app/
url process...it's just the GWT app. Personally I don't like the JSF/
JSP approach of redirecting to separate URLs/etc because I want one
look for all of my GWT app not different for login/logout etc. And
the redirect approach just doesn't seem to fit well in the RPC world.

Thanks!
-Dave

jhulford

unread,
Jul 25, 2012, 2:22:38 PM7/25/12
to google-we...@googlegroups.com
If you are serving your nocache files with your app server you could make a simple http filter, associate it with nocache requests and establish a session in the filter's service method. That way you know for certain you always have a session when your host page loads. Since you have access to the hosted mode jetty web.xml too, the same thing could be done the fix that as well.

dhoffer

unread,
Jul 26, 2012, 8:13:16 AM7/26/12
to google-we...@googlegroups.com
Yeah...I like your solution.  Any chance you could post samples of those fixes (or email them to me)?  I haven't done that before...

-Dave

jhulford

unread,
Jul 26, 2012, 9:25:22 AM7/26/12
to google-we...@googlegroups.com
Sorry, i'm away from my workspace for several days. Just read up on the Sevlet Filter interface and use your web.xml to associate it with requests for your nocache files. In the filter's doFilter method essentially all you'll do is call getSession to ensure a session is created and then pass through to the rest of your filter chain. It's quite easy.
Reply all
Reply to author
Forward
0 new messages