当前位置: 首页 > 知识库问答 >
问题:

如何覆盖JavaHTTP连接中的DNS

莫飞翮
2023-03-14

Curl具有手动指定主机解析到哪个IP的功能。例如:

curl https://google.com --resolve "google.com:443:173.194.72.113"

这在使用HTTPS时特别有用。如果它只是一个HTTP请求,我可以通过直接指定IP地址并添加主机头来实现同样的效果。但在HTTPS中,这将中断连接,因为SSL证书主机将与IP地址而不是主机头进行比较。

我的问题是,如何在Java中实现同样的事情?

共有2个答案

弓宏茂
2023-03-14

我手头没有代码,但是您也可以编写自己的SSL处理程序/检查程序,它可以适应或完全忽略所有的安全性。使用JDK基础网络,我们不得不完全忽略内部测试的SSL证书。应该很容易找到例子。

东方高洁
2023-03-14

如果使用阿帕奇的 HttpClient,您可以创建自定义 DNS 解析程序来检测要重定向的主机,然后提供替代 IP 地址。

注意:仅更改HTTPS请求的主机标头不起作用。它将抛出“javax.net.ssl.SSLPeerUnverifiedException”,迫使您信任坏证书,停止SNI工作,等等,所以这真的不是一个选项。自定义DnsResolver是我发现的唯一干净的方法,可以让这些请求在Java中使用HTTPS。

例:

/* Custom DNS resolver */
DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
    @Override
    public InetAddress[] resolve(final String host) throws UnknownHostException {
        if (host.equalsIgnoreCase("my.host.com")) {
            /* If we match the host we're trying to talk to, 
               return the IP address we want, not what is in DNS */
            return new InetAddress[] { InetAddress.getByName("127.0.0.1") };
        } else {
            /* Else, resolve it as we would normally */
            return super.resolve(host);
        }
    }
};

/* HttpClientConnectionManager allows us to use custom DnsResolver */
BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(
    /* We're forced to create a SocketFactory Registry.  Passing null
       doesn't force a default Registry, so we re-invent the wheel. */
    RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", SSLConnectionSocketFactory.getSocketFactory())
        .build(), 
    null, /* Default ConnectionFactory */ 
    null, /* Default SchemePortResolver */ 
    dnsResolver  /* Our DnsResolver */
    );

/* build HttpClient that will use our DnsResolver */
HttpClient httpClient = HttpClientBuilder.create()
        .setConnectionManager(connManager)
        .build();

/* build our request */
HttpGet httpRequest = new HttpGet("https://my.host.com/page?and=stuff"); 

/* Executing our request should now hit 127.0.0.1, regardless of DNS */
HttpResponse httpResponse = httpClient.execute(httpRequest);
 类似资料:
  • 我想在使用Html Unit时覆盖DNS解析,以便我可以测试负载均衡器后面的显式服务器。这应该在不更改etc/hosts文件的情况下完成。 这个问题得到了一个答案,如何用普通的java解决这个任务:如何在Java的HTTP连接中覆盖DNS 但我需要一个Html单元的解决方案。 Html单元使用apache httpclient。可以改变httpclient的连接管理器吗?(参见上面的其他问题)

  • 我正在尝试连接到外部web套接字服务器,该服务器不是我自己运行的。我想从localhost javascript文件连接到它,因此origin头的值为null。 我知道这是一项打击跨网站伪造的措施。然而,因为我在localhost,我应该能够伪造这一点,通过让Chrome发送自定义的Origin标头。 可能吗?(如果我需要延期,可以) 如果没有,实现上述目标的最佳选择是什么?谢谢你。

  • 问题内容: 我正在尝试Backbone.js,而我正在尝试的事情之一就是调用远程API,因此,据我了解的文档资料,我需要能够覆盖Backbone.sync 。 在文档本身中没有如何执行此操作的示例,并且似乎没有用于Backbone的google组…有人可以指出执行此操作的示例吗? 问题答案: 看看这个带注释的源示例,在该示例中,它们被本地存储替代项覆盖 基本上,Backbone.sync应该是一个

  • 配置没有选择我在属性文件中设置的最大池大小。当我签入显示为10的数据源对象时。如何覆盖hikari数据源中设置的默认值?

  • 在这个特定的示例中,我扩展了

  • 问题内容: 我目前在glassfish v2.1中使用基于身份的身份验证来登录用户,并且工作正常。我想切换到该网站,并希望能够获得最初请求的URL(即在重定向到登录页面之前),并在我的程序化登录代码中使用它,以便在身份验证后将用户重定向回请求的页面。 我已经看过源代码-在我的情况下,它是(catalina代码库),它将初始请求保存在会话中的对象中,但是该会话不是,因此没有直接方法可以访问它。 还是