我正在尝试为resty gwt编写我的自定义调度程序。
我的调度员RestyDispatcher
将包含两个过滤器:
BasicAuthHeaderDispatcherFilter
(将添加到每个请求安全令牌),ForbiddenDispatcherFilter
(将包含回调ForbiddenDispatcherCallback
) - 如果用户未登录,他的工作是重定向到登录页面。我有问题,我的过滤器是由gwt / restygwt注册的,不幸的是它们不起作用。
这是代码:
gin客户端模块
public class ClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
install(new DefaultModule.Builder().defaultPlace(Routing.PAGE.url).errorPlace(Routing.PAGE.url).unauthorizedPlace(Routing.LOGIN.url).tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
bind(CurrentUser.class).in(Singleton.class);
bind(UserLoginGatekeeper.class).in(Singleton.class);
// Load and inject CSS resources
bind(ResourceLoader.class).asEagerSingleton();
bind(RestyGwtConfig.class).asEagerSingleton();
}
}
RestyGwtConfig
public class RestyGwtConfig {
public RestyGwtConfig() {
final Dispatcher dispatcher = new RestyDispatcher();
GWT.log("--> RestyGwtConfig -> setDispatcher");
Defaults.setDispatcher(dispatcher);
UserCredentials.INSTANCE.setUserName("ronan");
UserCredentials.INSTANCE.setPassword("password");
}
static {
GWT.log("--> RestyGwtConfig -> setServiceRoot");
Defaults.setServiceRoot(new Resource(GWT.getModuleBaseURL()).resolve("../../cms/services").getUri());
}
}
RestyDispatcher
public class RestyDispatcher extends DefaultFilterawareDispatcher {
public RestyDispatcher() {
addFilter(new ForbiddenDispatcherFilter());
GWT.log("--> RestyDispatcher -> RestyDispatcher -> addFilter -> ForbiddenDispatcherFilter");
addFilter(new BasicAuthHeaderDispatcherFilter());
GWT.log("--> RestyDispatcher -> RestyDispatcher -> addFilter -> BasicAuthHeaderDispatcherFilter");
}
@Override
public Request send(Method method, RequestBuilder builder) throws RequestException {
GWT.log("SimpleDispatcher.Request.send.start");
Request send = builder.send();
GWT.log("SimpleDispatcher.Request.send.done");
return send;
}
}
ForbiddenDispatcherFilter
public class ForbiddenDispatcherFilter implements DispatcherFilter {
@Override
public boolean filter(Method method, RequestBuilder builder) {
GWT.log("--> ForbiddenDispatcherFilter -> filter -> setCallback");
builder.setCallback(new ForbiddenDispatcherCallback(method));
return true;
}
}
ForbiddenDispatcherCallback
public class ForbiddenDispatcherCallback implements RequestCallback {
protected RequestCallback requestCallback;
public ForbiddenDispatcherCallback(Method method) {
GWT.log("_________> ForbiddenDispatcherCallback " + method.toString());
this.requestCallback = method.builder.getCallback();
}
@Override
public void onResponseReceived(Request request, Response response) {
GWT.log("_________> ForbiddenDispatcherCallback -> onResponseReceived");
GWT.log(response.getStatusText() + response.getStatusCode());
if (response.getStatusCode() == Response.SC_FORBIDDEN || response.getStatusCode() == Response.SC_UNAUTHORIZED) {
// make a hard redirect to login page
Window.Location.assign("#/login");
} else {
requestCallback.onResponseReceived(request, response);
}
}
@Override
public void onError(Request request, Throwable exception) {
GWT.log("_________> ForbiddenDispatcherCallback -> onError");
requestCallback.onError(request, exception);
}
}
BasicAuthHeaderDispatcherFilter
final class BasicAuthHeaderDispatcherFilter implements DispatcherFilter {
public static final String AUTHORIZATION_HEADER = "Authorization";
@Override
public boolean filter(Method method, RequestBuilder builder) {
String basicAuthHeaderValue = createBasicAuthHeader(UserCredentials.INSTANCE.getUserName(), UserCredentials.INSTANCE.getPassword());
builder.setHeader(AUTHORIZATION_HEADER, basicAuthHeaderValue);
return true;
}
private String createBasicAuthHeader(String userName, String password) {
String credentials = userName + ":" + password;
String encodedCredentials = credentials;
return AUTHORIZATION_HEADER + ": Basic " + encodedCredentials;
}
}
当我运行app时,我会在Web浏览器控制台中获取此日志:
--> RestyGwtConfig -> setServiceRoot
SuperDevModeLogger.java:71--> RestyDispatcher -> RestyDispatcher -> addFilter -> ForbiddenDispatcherFilter
SuperDevModeLogger.java:71--> RestyDispatcher -> RestyDispatcher -> addFilter -> BasicAuthHeaderDispatcherFilter
SuperDevModeLogger.java:71--> RestyGwtConfig -> setDispatcher
所以我假设我的调度程序正确地注册了2个过滤器。不幸的是,我没有看到来自ForbiddenDispatcherFilter
的日志说它设置了我的回调ForbiddenDispatcherCallback
。我也没有看到提到的回调中的任何日志。
当我执行任何resty服务时,我会收到日志条目:
SimpleDispatcher.Request.send.start SuperDevModeLogger.java:71
SimpleDispatcher.Request.send.done XMLHttpRequest.java:305
POST http://localhost:8080/cms/services/authenticated/testService/setInfo 401 (Unauthorized)
因为我在文档中没有找到太多关于它的内容。为了达到这个目的,我基于这些例子:
但这些都没有指明。请帮忙。
答案 0 :(得分:1)
我在send
类中手动覆盖RestyDispatcher
方法,因此我的实现必须手动执行super.send(method, builder)
。或者我根本不应该覆盖send
方法。
所以RestyDispatcher
应该是这样的:
public class RestyDispatcher extends DefaultFilterawareDispatcher {
public RestyDispatcher() {
addFilter(new ForbiddenDispatcherFilter());
addFilter(new BasicAuthHeaderDispatcherFilter());
}
@Override
public Request send(Method method, RequestBuilder builder) throws RequestException {
return super.send(method, builder);
}
}
或
public class RestyDispatcher extends DefaultFilterawareDispatcher {
public RestyDispatcher() {
addFilter(new ForbiddenDispatcherFilter());
addFilter(new BasicAuthHeaderDispatcherFilter());
}
}
答案 1 :(得分:0)
我的解决方案是手动执行filter
方法。
我不知道这是不是很好的解决方案。我假设这是错误,因为filter
方法应该由RestyGWT调用,因为它在interface DispatcherFilter
中声明并在DefaultFilterawareDispatcher
类中实现,如下所示:
package org.fusesource.restygwt.client.dispatcher;
public class DefaultFilterawareDispatcher implements FilterawareDispatcher {
@Override
public Request send(Method method, RequestBuilder builder) throws RequestException {
for (DispatcherFilter f : dispatcherFilters) {
if (!f.filter(method, builder)) {
// filter returned false, no continue
if (GWT.isClient() && LogConfiguration.loggingIsEnabled()) {
Logger.getLogger(DefaultFilterawareDispatcher.class.getName())
.fine(f.getClass() + " told me not to continue filtering for: "
+ builder.getHTTPMethod() + " " + builder.getUrl());
}
return null;
}
}
return builder.send();
}
}
这是我的代码实现:
public class ClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(RestyGwtConfig.class).asEagerSingleton();
install(new DefaultModule.Builder().defaultPlace(Routing.PAGE.url).errorPlace(Routing.PAGE.url).unauthorizedPlace(Routing.LOGIN.url).tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
bind(CurrentUser.class).in(Singleton.class);
bind(IsAdminGatekeeper.class).in(Singleton.class);
bind(UserLoginGatekeeper.class).in(Singleton.class);
}
}
public class RestyGwtConfig {
static {
Defaults.setDispatcher(new RestyDispatcher());
Defaults.setServiceRoot(new Resource(GWT.getModuleBaseURL()).resolve("../../cms/services").getUri());
}
}
public class RestyDispatcher extends DefaultFilterawareDispatcher {
public RestyDispatcher() {
addFilter(new ForbiddenDispatcherFilter());
addFilter(new BasicAuthHeaderDispatcherFilter());
}
@Override
public Request send(Method method, RequestBuilder builder) throws RequestException {
for (DispatcherFilter e : this.dispatcherFilters) {
e.filter(method, builder);
}
return builder.send();
}
}
如果我错了,请纠正我。