nats.java
nats.java copied to clipboard
Authenticated Proxy support for WebSocket client
Feature Request
I am currently in the situation that I'd like to connect to NATS from behind an authenticated HTTP Proxy. And while the library handles proxying just fine, it can't handle authenticated proxies.
Use Case: The WebSocket Client can already handle proxies but not if it's an HTTP Proxy requiring authentication during CONNECT
Proposed Change:
Essentially here (https://github.com/nats-io/nats.java/blob/ba5dd0d85e7cec015e5d05c4cd44c95be0399ec1/src/main/java/io/nats/client/support/WebSocket.java#L53) the new code would need to handle authentication required proxy responses and react accordingly by sending the required headers as part of a CONNECT request.
Who Benefits From The Change(s)?
Mainly people who're in the same situation i am, that is WebSocket + Authed Proxy
Alternative Approaches
I attempted to do this myself by slightly abusing the ability to set the DataPort class on the connection builder. However I noticed that the NatsConnection that is part of the parameters of said interface is only packaged scope, so I can't override it either.
Can you make your change in the same package? I think this would be a useful contribution to the project.
So I started digging into it, however my implementation plan doesn't work.
In presence of an http Proxy the new Socket that is created in SocketDataPort actually creates an HttpConnectSocketImpl underneath. This means at the point where we are on the WebSocket. This will do the http CONNECT as part of the sockets connect and in WebSocket it's too late and the socket is already closed because we got a 407 response.
HttpConnectSocketImpl uses HttpUrlConnection internally and sets the proxy there but at least in Java 8 (the buildtarget of this project) the Socket does not support setting a specific Authenticator. Since Java 9 HttpUrlConnection does permit to do so, so maybe it'd be possible on a higher build target?
Anyway, what at least works due to the way the Java internal Sockets are wired is to set the system wide Authenticator using Authenticator.setDefault which i really wanted to avoid.
So I'm out of ideas sadly, if someone has a better idea to tackle this let me know and I'll give it another crack.
@GrafBlutwurst Can you see if this change, released in 2.18.0, fixes your issue? Change: https://github.com/nats-io/nats.java?tab=readme-ov-file#reverse-proxy