3

XSRF を webapp で動作させようとしましたが、役に立ちませんでした。典型的なログインの実装を見ています。

私はGoogleのコードに従っています。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ファイルで拡張されました。サーバー上で他の変更は必要ないことを理解しています。RpcTokenhere を返すメソッド (および実装しているインターフェイス)など、他に何か追加する必要がありますか?

クライアント側では、注釈を使用します。

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

これはおそらく私が何かを見逃しているところです。Google はヒントで次のように述べていますTip: To specify which RpcToken implementation GWT should generate serializers for use @RpcTokenImplementation annotation.

私の非同期インターフェースは次のようなものです:

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

次に、実際の RPC 呼び出しのために、コードを xsrf トークン リクエストにラップします。Googleのものと同じコードを使用します:

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 ページなしでこれを実行する方法がわかりません。彼のコードは、Google のコード例 (つまり、彼は getNewXsrfToken を呼び出していない) からも分岐していますが、それが XSRF を処理する Google の「推奨される」方法であるかどうかはわかりません。

私が欠けているものに関するアイデアはありますか? ありがとう。

編集

以下の解決策...

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 に答える