GWT (2.4.0) + XSRF

Starałem się, aby XSRF pracował na aplikacji internetowej bezskutecznie. Patrzę na typową implementację logowania.

śledzęKod Google. Zmieniłem plik web.xml, aby zawierał:

<code><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>
</code>

i rozszerzonyXsrfProtectedServiceServlet na serwerze Impl pliku mojej usługi logowania. Rozumiem, że żadna inna zmiana nie jest potrzebna na serwerze. Czy muszę dodać coś innego, na przykład metodę zwracającąRpcToken tutaj (jak również w interfejsie, który implementuję)?

Po stronie klienta używam adnotacji.

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

Prawdopodobnie tutaj czegoś mi brakuje. Google mówi na końcu:Tip: To specify which RpcToken implementation GWT should generate serializers for use @RpcTokenImplementation annotation. Nie wiem, co to znaczy lub czy potrzebuję tutaj innej metody, aby zwrócić RpcToken.

Mój interfejs asynchroniczny wygląda następująco:

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

Następnie dla mojego rzeczywistego wywołania RPC zawijam mój kod wokół żądania tokenu xsrf. Używam kodu identycznego z google:

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

Narzekam, że wywołanie getNewXsrfToken kończy się niepowodzeniem, ponieważ nie zna tej lokalizacji xsrf z połączenia tutaj:GWT.getModuleBaseURL() + "xsrf". Mam wrażenie, że brakuje uścisku tokena, który powoduje ten błąd, ale nie jestem pewien.

Na koniec próbowałem również wdrożyćKod Nicka Siderakisa ale jego przykład używa strony JSP, która pyta serwer:XsrfTokenUtil.getToken(request.getSession().getId()). Nie chcę używać stron JSP i nie zorientowałem się, jak to zrobić bez strony jsp. Jego kod również odbiega od przykładu kodu Google (tj. Nie wywołuje getNewXsrfToken), którego nie wiem, czy jest to „preferowany” sposób Google'a do radzenia sobie z XSRF.

Jakieś pomysły dotyczące tego, czego brakuje? Dzięki.

EDYTOWAĆ

Rozwiązanie poniżej ...

questionAnswers(1)

yourAnswerToTheQuestion