title: GWT (2.4.0) + XSRF
body: <p>I've been trying to get XSRF working on a webapp to no avail.
  I am looking at a typical login implementation.</p>
  
  <p>I am following <a href="https://developers.google.com/web-toolkit/doc/latest/DevGuideSecurityRpcXsrf" rel="nofollow">Google's code</a>.
  I changed my web.xml to include:</p>
  
  <pre><code>&lt;servlet&gt;
      &lt;servlet-name&gt;xsrf&lt;/servlet-name&gt;
      &lt;servlet-class&gt;com.google.gwt.user.server.rpc.XsrfTokenServiceServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;xsrf&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/gwt/xsrf&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  
  &lt;context-param&gt;
      &lt;param-name&gt;gwt.xsrf.session_cookie_name&lt;/param-name&gt;
      &lt;param-value&gt;JSESSIONID&lt;/param-value&gt;
  &lt;/context-param&gt;
  </code></pre>
  
  <p>and extended <code>XsrfProtectedServiceServlet</code> on the server Impl file of my login service. It is my understanding that no other change is needed on the server. Do I need to add anything else, such as a method that returns an <code>RpcToken</code> here (as well as in the interface I am implementing)?</p>
  
  <p>On the client side, I use annotations.</p>
  
  <pre><code>@XsrfProtect
  @RemoteServiceRelativePath("login")
  public interface LoginService extends RemoteService {
      String check(String user, String pass) throws IllegalArgumentExceptionhere;
  }
  </code></pre>
  
  <p>This is probably where I am missing something. Google says on the tip: <code>Tip: To specify which RpcToken implementation GWT should generate serializers for use @RpcTokenImplementation annotation.</code> Not sure what that means or if I need another method here to return an RpcToken.</p>
  
  <p>My async interface is like this:</p>
  
  <pre><code>public interface LoginServiceAsync {
      //Returns the Session ID
      void check(String user, String pass, AsyncCallback&lt;String&gt; callback);
  }
  </code></pre>
  
  <p>Then for my actual RPC call, I wrap my code around the xsrf token request. I use code identical to google's:</p>
  
  <pre><code>XsrfTokenServiceAsync xsrf = (XsrfTokenServiceAsync)GWT.create(XsrfTokenService.class);
  ((ServiceDefTarget)xsrf).setServiceEntryPoint(GWT.getModuleBaseURL() + "xsrf");
  xsrf.getNewXsrfToken(new AsyncCallback&lt;XsrfToken&gt;() {
  
      public void onSuccess(XsrfToken token) {
          LoginServiceAsync rpc = (LoginServiceAsync)GWT.create(LoginService.class);
          ((HasRpcToken) rpc).setRpcToken(token);
  
          // make XSRF protected RPC call
          rpc.check(user, pass, new AsyncCallback&lt;String&gt;() {
              // ...
          });
      }
  
      public void onFailure(Throwable caught) {
          try {
               throw caught;
          } catch (RpcTokenException e) {
          // Can be thrown for several reasons:
          //   - duplicate session cookie, which may be a sign of a cookie
          //     overwrite attack
          //   - XSRF token cannot be generated because session cookie isn't
          //     present
          } catch (Throwable e) {
          // unexpected
      }
  });
  </code></pre>
  
  <p>The complain is I that the call to getNewXsrfToken fails as it doesn't know that xsrf location from the call here: <code>GWT.getModuleBaseURL() + "xsrf"</code>. I get the feeling there is a token handshake missing which causes this error, but I am not sure.</p>
  
  <p>Lastly, I also tried implementing <a href="http://code.google.com/p/xsrf-safe/" rel="nofollow">Nick Siderakis' code</a> but his example uses a JSP page which asks the server: <code>XsrfTokenUtil.getToken(request.getSession().getId())</code>. I do not want to use JSP pages and I have not figured out how to perform this without a jsp page. His code also diverges from the Google code example (i.e. he doesn't call getNewXsrfToken) which I do not know if it's the "prefered" google way of dealing with XSRF.</p>
  
  <p>Any ideas as to what I am missing? Thanks.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Solution below...</p>