3

我一直试图让 XSRF 在 webapp 上工作但无济于事。我正在研究一个典型的登录实现。

我正在关注谷歌的代码。我将 web.xml 更改为包括:

<servlet>
    <servlet-name>xsrf</servlet-name>
    <servlet-class>com.google.gwt.user.server.rpc.XsrfTokenServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>xsrf</servlet-name>
    <url-pattern>/gwt/xsrf</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>gwt.xsrf.session_cookie_name</param-name>
    <param-value>JSESSIONID</param-value>
</context-param>

XsrfProtectedServiceServlet并在我的登录服务的服务器 Impl 文件上进行了扩展。据我了解,服务器上不需要进行其他更改。我是否需要添加任何其他内容,例如返回RpcToken此处的方法(以及在我正在实现的接口中)?

在客户端,我使用注释。

@XsrfProtect
@RemoteServiceRelativePath("login")
public interface LoginService extends RemoteService {
    String check(String user, String pass) throws IllegalArgumentExceptionhere;
}

这可能是我遗漏的地方。谷歌在提示中说:Tip: To specify which RpcToken implementation GWT should generate serializers for use @RpcTokenImplementation annotation.不确定这意味着什么,或者我是否需要另一种方法来返回 RpcToken。

我的异步接口是这样的:

public interface LoginServiceAsync {
    //Returns the Session ID
    void check(String user, String pass, AsyncCallback<String> callback);
}

然后对于我的实际 RPC 调用,我将我的代码包装在 xsrf 令牌请求周围。我使用与谷歌相同的代码:

XsrfTokenServiceAsync xsrf = (XsrfTokenServiceAsync)GWT.create(XsrfTokenService.class);
((ServiceDefTarget)xsrf).setServiceEntryPoint(GWT.getModuleBaseURL() + "xsrf");
xsrf.getNewXsrfToken(new AsyncCallback<XsrfToken>() {

    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<String>() {
            // ...
        });
    }

    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
    }
});

抱怨是我对 getNewXsrfToken 的调用失败,因为它不知道来自此处调用的 xsrf 位置:GWT.getModuleBaseURL() + "xsrf"。我感觉缺少导致此错误的令牌握手,但我不确定。

最后,我还尝试实现Nick Siderakis 的代码,但他的示例使用了一个询问服务器的 JSP 页面:XsrfTokenUtil.getToken(request.getSession().getId()). 我不想使用 JSP 页面,而且我还没有弄清楚如何在没有 jsp 页面的情况下执行此操作。他的代码也不同于谷歌代码示例(即他不调用 getNewXsrfToken),我不知道这是否是谷歌处理 XSRF 的“首选”方式。

关于我缺少什么的任何想法?谢谢。

编辑

下面的解决方案...

4

1 回答 1

4

好的,我发现了问题。我不得不在上面的代码中将 GWT.getModuleBaseURL() + "xsrf" 更改为 "gwt/xsrf",因为我怀疑它没有指向正确的位置。另外,服务器找不到 JSESSIONID cookie,所以我跟着这个添加了 Cookies.setCookie("JSESSIONID", "JSESSIONID", null, null, "/", false); 在我的 onModuleLoad() 里面。做到了。干杯。

于 2012-04-25T09:07:04.040 回答