Skip to content

Silent failure to send backend request after authentication with OAuth2 #101

Description

@tsegismont

When the Vert.x Web Proxy handler is installed after an OAuth2 handler, the proxy silently fails to send the request to the backend just after authentication.

If the user is already authenticated with the OAuth2 provider, the proxy successfully sends the request.

Here's an example setup:

        router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

        OAuth2Auth authProvider = GithubAuth.create(vertx, clientId, clientSecret);
        router.route("/protected").handler(OAuth2AuthHandler.create(vertx, authProvider, "http://localhost:4180/oauth2/callback")
                .setupCallback(router.route("/oauth2/callback"))
                .withScope("user:email"));

        router.route("/protected").handler(rc -> {
            Context context = vertx.getOrCreateContext();
            User user = rc.user();
            Session session = rc.session();
            JsonObject userInfo = session.get("userInfo");
            if (userInfo == null) {
                authProvider.userInfo(user).onComplete(ar -> {
                    if (ar.succeeded()) {
                        session.put("userInfo", ar.result());
                        context.putLocal("userInfo", ar.result());
                        context.putLocal("accessToken", user.get("access_token"));
                        rc.next();
                    } else {
                        session.destroy();
                        rc.fail(ar.cause());
                    }
                });
            } else {
                context.putLocal("userInfo", userInfo);
                context.putLocal("accessToken", user.get("access_token"));
                rc.next();
            }
        });

        HttpClient proxyClient = vertx.createHttpClient();
        HttpProxy httpProxy = HttpProxy.reverseProxy(proxyClient)
                .addInterceptor(new ProxyInterceptor() {
                    @Override
                    public Future<ProxyResponse> handleProxyRequest(ProxyContext pc) {
                        ProxyRequest proxyRequest = pc.request();
                        MultiMap headers = proxyRequest.headers();
                        headers.remove("Cookie");
                        Context context = vertx.getOrCreateContext();
                        JsonObject userInfo = context.getLocal("userInfo");
                        if (userInfo != null) {
                            headers.set("X-Forwarded-User", userInfo.getString("login"));
                            headers.set("X-Forwarded-Email", userInfo.getString("email"));
                            headers.set("X-Forwarded-Access-Token", context.<String>getLocal("accessToken"));
                        }
                        return pc.sendRequest();
                    }
                });
        router.route().handler(ProxyHandler.create(httpProxy, 8080, "localhost"));

With debugging, it appears that when the proxy sets up the pipe on the incoming request, no callback is invoked:

Pipe<Buffer> pipe = body.stream().pipe();
pipe.endOnComplete(true);
pipe.endOnFailure(false);
pipe.to(request, ar -> {
if (ar.failed()) {
request.reset();
}
});
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions