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ファイルで拡張されました。サーバー上で他の変更は必要ないことを理解しています。RpcToken
here を返すメソッド (および実装しているインターフェイス)など、他に何か追加する必要がありますか?
クライアント側では、注釈を使用します。
@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 の「推奨される」方法であるかどうかはわかりません。
私が欠けているものに関するアイデアはありますか? ありがとう。
編集
以下の解決策...