While waiting for kristian's answer, I'd like to give you my nice solution for the
XSRFTokenDispatcherFilter using GIN:
With GIN I create 3 singletons:
1. XSRFToken
2. XSRFTokenDispatcherFilter
3. DefaultFilterawareDispatcher
public class RestModule extends AbstractGinModule {
@Override
protected void configure() {}
@Provides @Singleton
public XSRFToken provideXSRFToken() {
XSRFToken xsrfToken = new XSRFToken();
// get the CSRF token from the HTML document and initialize the XSRFToken
NodeList<MetaElement> metaTags = Document.get().getElementsByTagName(MetaElement.TAG).cast();
for(int i=0; i<metaTags.getLength(); i++) {
if(metaTags.getItem(i).getName().equals(Config.RAILS_CSRF_TOKEN_META_TAG_NAME)) {
xsrfToken.setToken(metaTags.getItem(i).getContent());
break;
}
}
return xsrfToken;
}
@Provides @Singleton @Inject
public XSRFTokenDispatcherFilter provideXSRFTokenDispatcherFilter(XSRFToken xsrf) {
return new XSRFTokenDispatcherFilter(xsrf);
}
@Provides @Singleton
public FilterawareDispatcher provideDispatcher() {
return new DefaultFilterawareDispatcher();
}
}
The XSRFToken is getting initialized within its provider. As I'm using Rails, I fetch the token from the HTML document.
Next XSRFTokenDispatcherFilter needs an instance of XSRFToken in its constructor, so I simply inject it.
The last one is the FilterawareDispatcher provider. I know that GIN is unnecessary here, but I wanted to keep it all in one place ;-)
So next let's have a look at the Ginjector:
@GinModules({ RestModule.class })
public interface MyGinjector extends Ginjector {
XSRFTokenDispatcherFilter getXSRFTokenDispatcherFilter();
FilterawareDispatcher getFilterawareDispatcher();
}
I need those two, because I have to add the XSRFDispatcherFilter to the FilterawareDispatcher within my applications EntryPoint. I don't need the XSRFToken, 'cause it's already set for the XSRFTokenDispatcherFilter.
So here's my EntryPoint:
public class PostGISgwt implements EntryPoint {
private final MyGinjector ginjector = GWT.create(MyGinjector.class);
public void onModuleLoad() {
initRestyGwt();
}
private void initRestyGwt() {
FilterawareDispatcher filterawareDispatcher = ginjector.getFilterawareDispatcher();
filterawareDispatcher.addFilter(ginjector.getXSRFTokenDispatcherFilter());
Defaults.setDispatcher(filterawareDispatcher);
}
}
If we have to change the XSRF token at some point, we simply inject it and call setToken(String token).
Here's an example for gwt-platform, where I receive a new CSRF token on sign out (the onSignOut method get's called by the View when the user clicks the sign out button):
public class SignOutPresenterWidget
extends PresenterWidget<SignOutPresenterWidget.MyView>
implements SessionUiHandlers {
public interface MyView extends View, HasUiHandlers<SessionUiHandlers> {}
@Inject SessionService sessionService;
@Inject XSRFToken xsrfToken;
@Inject
public SignOutPresenterWidget(EventBus eventBus, MyView view) {
super(eventBus, view);
getView().setUiHandlers(this);
}
@Override
public void onSignOut() {
sessionService.signOut(new MethodCallback<SignOutResponse>() {
@Override
public void onSuccess(Method method, SignOutResponse response) {
xsrfToken.setToken(response.getCsrfToken());
}
@Override
public void onFailure(Method method, Throwable exception) {
// display an error message
}
});
}
}
Maybe someone is interested in this kind of solution ;-)
(I'll have a look at XSRFTokenCallbackFilter, maybe this could make the "set token on sign out" a little bit easier ?!)
Cheers!