Binding CXF Client Source IP Address

I have a CXF client that connects to a web service. This client is installed on a computer that has two IP addresses on the same network (for example, 172.16.1.101 and 172.16.1.102).

How to configure the CXF client to use a specific source IP address so that the server sees requests coming from that specific IP address and not another?

If I had access to Socket, I would do something like:

Socket s = new Socket(); s.bind(new InetSocketAddress("172.16.1.102", 0)); //this Ip address is the one I need to specify s.connect(new InetSocketAddress("google.com", 80)); 

Can I configure the sockets created by CXF to specify the source IP address?

EDIT: I need to specify the source IP address, as there is a firewall between the client and the web server that has rules for one of the IP addresses (connections coming from another IP address are blocked).

+8
java web-services sockets cxf
source share
3 answers

Custom URLStreamHandlerFactory works.

Example:

  ... URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() { @Override public URLStreamHandler createURLStreamHandler(String protocol) { if (protocol.equals("http")) { return new HttpHandler(); } else if (protocol.equals("https")) { return new sun.net.www.protocol.https.Handler(); } return null; } }); ... private class HttpHandler extends java.net.URLStreamHandler { protected int getDefaultPort() { return 80; } @Override protected URLConnection openConnection(URL u) throws IOException { return openConnection(u, (Proxy) null); } @Override protected URLConnection openConnection(URL u, Proxy p) throws IOException { return new HttpURLConnection(u, p) { @Override protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout) throws IOException { return new HttpClient(url, (String) null, -1, true, connectTimeout) { @Override protected Socket createSocket() throws IOException { Socket s = new Socket(); s.bind(new InetSocketAddress(InetAddress.getByName("1.2.3.4"), 0)); // yours IP here return s; } }; } @Override protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout, boolean useCache) throws IOException { return getNewHttpClient(url, p, connectTimeout); } }; } } 

For HTTPS, you can also use custom SSLSocketFactory

 HttpsURLConnection.setDefaultSSLSocketFactory(...); 
+1
source share

The CXF client uses java.net.URLConnection to connect to the service. URLConnection can be configured to select a local IP address (see How to specify a local address on java.net.URLConnection? )

 URL url = new URL(yourUrlHere); Proxy proxy = new Proxy(Proxy.Type.DIRECT, new InetSocketAddress( InetAddress.getByAddress( new byte[]{your, ip, interface, here}), yourTcpPortHere)); URLConnection conn = url.openConnection(proxy); 

I checked the cxf-rt-rs-client and cxf-rt-transports-http artifact code to see how CXF creates the connection. In ProxyFactory , this is the code to create the Proxy object required by UrlConnection

 private Proxy createProxy(final HTTPClientPolicy policy) { return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()), new InetSocketAddress(policy.getProxyServer(), policy.getProxyServerPort())); } 

As you can see, there is no way to configure the IP address, so I'm afraid that the answer to the question is, you cannot configure the source IP address using CXF

But, I think it would not be so difficult to change the source code to allow setting the source IP address

HTTPClientPolicy

Add the following code to org.apache.cxf.transports.http.configuration.HTTPClientPolicy in cxf-rt-transports-http

 public class HTTPClientPolicy { protected byte[] sourceIPAddress; protected int port; public boolean isSetSourceIPAddress(){ return (this.sourceIPAddress != null); } 

Proxyfactory

Change the following code to org.apache.cxf.transport.http.ProxyFactory to cxf-rt-transports-http

  //added || policy.isSetSourceIPAddress() //getProxy() calls finally to createProxy public Proxy createProxy(HTTPClientPolicy policy, URI currentUrl) { if (policy != null) { // Maybe the user has provided some proxy information if (policy.isSetProxyServer() || policy.isSetSourceIPAddress()) && !StringUtils.isEmpty(policy.getProxyServer())) { return getProxy(policy, currentUrl.getHost()); } else { // There is a policy but no Proxy configuration, // fallback on the system proxy configuration return getSystemProxy(currentUrl.getHost()); } } else { // Use system proxy configuration return getSystemProxy(currentUrl.getHost()); } } //Added condition to set the source IP address (is set) //Will work also with a proxy private Proxy createProxy(final HTTPClientPolicy policy) { if (policy.isSetSourceIPAddress()){ Proxy proxy = new Proxy(Proxy.Type.DIRECT, new InetSocketAddress( InetAddress.getByAddress( policy.getSourceIPAddress(), policy.getPort())); } else { return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()), new InetSocketAddress(policy.getProxyServer(), policy.getProxyServerPort())); } } 

Using

 Client client = ClientProxy.getClient(service); HTTPConduit http = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setSourceIPAddress(new byte[]{your, ip, interface, here})); httpClientPolicy.setPort(yourTcpPortHere); http.setClient(httpClientPolicy); 
+5
source share

Not sure if I understood your question correctly, but I don’t think you need to specifically configure the IP address on the client so that the server reads `

 Message message = PhaseInterceptorChain.getCurrentMessage(); HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST); request.getRemoteAddr() 

Add this code to the server, and it can really find the IP request, and you can do a comparison on the server for the IP address. Let me know if this is what you are looking for.

Edit: -----

Well, I understand that the firewall does not see the IP address included in the header or payload in the message. It checks the IP address of the source server.

Correct me if I am wrong, but I feel that if you are deploying your client on this server for which a firewall rule has been added and called on the server, there is no reason why it should not work.

Let me know what error you get, say a stack trace or something else, and we can see what happens.

0
source share

All Articles