Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tsegismont opened this issue Oct 25, 2024 · 3 comments
Open
Assignees
Labels
bug Something isn't working
Milestone

Comments

@tsegismont
Copy link
Contributor

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();
}
});
}

@tsegismont tsegismont added the bug Something isn't working label Oct 25, 2024
@tsegismont tsegismont added this to the 4.5.11 milestone Oct 25, 2024
@tsegismont tsegismont self-assigned this Oct 25, 2024
@skoya
Copy link

skoya commented Oct 28, 2024

I also had a similar issue. I logged it under web by mistake:

vert-x3/vertx-web#2664

@skoya
Copy link

skoya commented Nov 4, 2024

Why would this be different in the flow for oauth2 calls vs non oauth calls?

@tsegismont
Copy link
Contributor Author

@skoya it may be because the body has been consumed already and the pipe doesn't get any completion event

@vietj vietj modified the milestones: 4.5.11, 4.5.12 Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants