如何修复 "Internal Server Error" 在自定义 AuthProvider 中使用 EventBus

How to fix "Internal Server Error" on using EventBus in custom AuthProvider

在自定义 AuthProvider 中使用 vert.x EventBus 确实会在将来完成时提供 "Internal Server Error"。

构建了一个自定义的 AuthProvider,它从 EventBus 获取用户数据。 EventBus 和用户数据正确返回,但在 succeededFuture() 处理程序之后我只得到 "Internal Server Error"。我搞砸了 EventBus.send() 的处理程序和异步模式吗?

package tld.domain.auth;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.AuthProvider;
import io.vertx.ext.auth.User;

public class MyAuthProvider implements AuthProvider {

    private final EventBus eventBus;

    public MyAuthProvider(Vertx vertx) {
        this.eventBus = vertx.eventBus();
    }

    public static MyAuthProvider create(Vertx vertx) {
        return new MyAuthProvider(vertx);
    }

    @Override
    public void authenticate(JsonObject jsonObject, Handler<AsyncResult<User>> handler) {

        try {
            eventBus.send("hello", null, message -> {
                try {
                    if (true) {
                        handler.handle(Future.succeededFuture(new MyAuthUser()));
                    } else {
                        handler.handle(Future.failedFuture("failed by purpose"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

package tld.domain.auth;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.AbstractUser;
import io.vertx.ext.auth.AuthProvider;

public class MyAuthUser extends AbstractUser {
    @Override
    protected void doIsPermitted(String s, Handler<AsyncResult<Boolean>> handler) {
        handler.handle(Future.succeededFuture(true));
    }

    @Override
    public JsonObject principal() {
        return null;
    }

    @Override
    public void setAuthProvider(AuthProvider authProvider) {

    }
}

并且在垂直

_router = Router.router(vertx);

MyAuthProvider authProvider = MyAuthProvider.create(vertx);

// router auth session storage
_router.route().handler(CookieHandler.create());
_router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)).setAuthProvider(authProvider));

// router basic auth
AuthHandler basicAuthHandler = BasicAuthHandler.create(authProvider);
_router.route().handler(basicAuthHandler);

_router.route().handler(BodyHandler.create());
_router.get("/hello").handler(this::getHelloHandler);

删除 eventbus.send() 使示例工作(获得正确的响应)。添加事件总线会使结果变得混乱,只会得到 "Internal Server Error" 而不是响应。

处理程序和异步 eventbus.send() 是否存在问题,或者我是否遗漏了一些其他重要的 vert.x 概念?

我通过交换 BodyHandler 和 AuthHandler 注册顺序找到了解决方案。

// BodyHandler FIRST !!!
_router.route().handler(BodyHandler.create());
// AuthHandler SECOND
_router.route().handler(_basicAuthHandler);
// DO NOT CREATE BodyHandler AFTER AuthHandler
//_router.route().handler(BodyHandler.create());