vertx-http-proxy icon indicating copy to clipboard operation
vertx-http-proxy copied to clipboard

Silent failure to send backend request after authentication with OAuth2

Open tsegismont opened this issue 1 year ago • 3 comments

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:

https://github.com/eclipse-vertx/vertx-http-proxy/blob/5ec808d0122d955beb1fdf892d341ee540119e83/src/main/java/io/vertx/httpproxy/impl/ProxiedRequest.java#L195-L203

tsegismont avatar Oct 25 '24 16:10 tsegismont

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

https://github.com/vert-x3/vertx-web/issues/2664

skoya avatar Oct 28 '24 08:10 skoya

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

skoya avatar Nov 04 '24 13:11 skoya

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

tsegismont avatar Nov 05 '24 14:11 tsegismont

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

I can confirm this is the case, in io.vertx.httpproxy.impl.ReverseProxy handle method Exception caught is: java.lang.IllegalStateException: Request has already been read

ross-oreto avatar Aug 30 '25 19:08 ross-oreto

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

I can confirm this is the case, in io.vertx.httpproxy.impl.ReverseProxy handle method Exception caught is: java.lang.IllegalStateException: Request has already been read

Any way it can be fixed?

skoya avatar Sep 19 '25 19:09 skoya