首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绑定CXF客户端IP地址

绑定CXF客户端IP地址
EN

Stack Overflow用户
提问于 2016-07-31 23:39:27
回答 3查看 1.3K关注 0票数 10

我有一个连接到Web服务的CXF客户端。此客户端安装在一台机器上,tha在同一网络中有两个IP地址(例如172.16.1.101和172.16.1.102)。

如何将CXF客户端配置为使用特定的源IP地址,以便服务器能够看到来自该特定IP地址的请求,而不是其他请求?

如果我能够访问套接字,我会做如下的事情:

代码语言:javascript
复制
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));

是否可以配置CXF创建的套接字,以便指定源IP地址?

编辑:我需要指定源IP地址,因为在客户端和web服务器之间有一个防火墙,其中一个IP地址有规则(来自其他IP地址的连接被阻塞)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-04-05 09:00:26

定制的URLStreamHandlerFactory可以工作。

示例:

代码语言:javascript
复制
        ...
        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);
            }

        };
    }
}

对于HTTPS,也可以使用自定义SSLSocketFactory。

代码语言:javascript
复制
HttpsURLConnection.setDefaultSSLSocketFactory(...);
票数 1
EN

Stack Overflow用户

发布于 2016-08-03 07:56:05

CXF客户端使用java.net.URLConnection连接到服务。可以将URLConnection配置为以这种方式选择本地IP地址(请参阅如何在java.net.URLConnection上指定本地地址?)

代码语言:javascript
复制
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);

我检查了工件cxf-rt-rs-clientcxf-rt-transports-http的代码,以了解CXF是如何创建连接的。在ProxyFactory中,创建UrlConnection所需的Proxy对象的代码

代码语言:javascript
复制
private Proxy createProxy(final HTTPClientPolicy policy) {
    return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()),
                     new InetSocketAddress(policy.getProxyServer(),
                                           policy.getProxyServerPort()));
}

如您所见,无法配置IP地址,因此我担心问题的答案是--您不能使用CXF配置源IP地址。

但是,我认为修改源代码以允许设置源IP地址并不困难。

HTTPClientPolicy

将以下代码添加到org.apache.cxf.transports.http.configuration.HTTPClientPolicy at cxf-rt-transports-http

代码语言:javascript
复制
public class HTTPClientPolicy {
    protected byte[] sourceIPAddress;
    protected int port;

    public boolean isSetSourceIPAddress(){
        return (this.sourceIPAddress != null);
    }

ProxyFactory

将以下代码修改为org.apache.cxf.transport.http.ProxyFactory at cxf-rt-transports-http

代码语言:javascript
复制
 //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()));
    }                
}

使用

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2016-08-01 00:11:40

不确定我是否正确地理解了您的问题,但我不认为您需要在客户机上专门设置一个IP地址,以便服务器读取

代码语言:javascript
复制
Message message = PhaseInterceptorChain.getCurrentMessage();
HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);
request.getRemoteAddr()

在服务器上添加此代码,它实际上可以从请求中找到IP,您可以在服务器上对IP进行比较。如果这是你要找的,请告诉我。

编辑:?

嗯,我的理解是防火墙没有看到消息头或负载中的IP。它检查原始服务器的IP。

如果我错了,请纠正我,但我觉得如果您将客户端部署在添加了防火墙规则的服务器上,并调用服务器,则没有理由不工作。

让我知道你得到了什么样的错误,比如说堆栈跟踪或者什么的,我们就可以看到发生了什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38689303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档