我的Android应用程序用于客户的内部网络,部分配置涉及到他们输入Web服务的URL。
Android从一开始似乎就无法看到内部网络中的主机名,所以直到现在我一直建议人们使用他们服务器的IP地址。最近出现的一个问题是,一个客户在他们的服务器上应用了SSL,这意味着URL只能通过https访问,而自签名证书当然与主机名匹配,而不是IP地址。通过IP地址请求URL不再有效,无论您指定http还是https。
谷歌搜索了几天,建议要么根设备和修改主机文件,或提供一个内部DNS的TLS服务器,但这两个选项对我来说都不可用。
解析内部主机名肯定不会这么难吧?
我不完全确定这是一个代码问题,因为这个问题在Chrome中是可以重现的,但这里是我的代码:
protected JSONObject doInBackground(String... params) {
try {
URL url = new URL("http://officeserver/PTSWeb/PTSCommsServer.asmx");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
HttpURLConnection.setFollowRedirects(false);
huc.setConnectTimeout(5 * 1000);
huc.setRequestMethod("GET");
huc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
huc.connect(); //FAILS HERE WITH UNABLE TO RESOLVE HOST
BufferedReader in = new BufferedReader(new InputStreamReader(huc.getInputStream()));
String result = "";
StringBuilder total = new StringBuilder();
for (String line; (line = in.readLine()) != null; ) {
total.append(line).append('\n');
}
in.close();
result = total.toString();
return new JSONObject(result);
} catch (Exception e) {
try {
JSONObject MyErrorJSON = new JSONObject();
MyErrorJSON.accumulate("WasError", "True");
MyErrorJSON.accumulate("ResponseText", e.toString());
return MyErrorJSON;
} catch (Exception x) {
return null;
}
}
}
2条答案
按热度按时间ljo96ir51#
在过去的12个月里,这个问题已经收到了很多意见,所以我想我应该在这里放弃我的"答案",以防不仅仅是我面临这个问题。
六年多来,我一直在回避这个问题,在过去的两年里,它成了一个令人头疼的问题。我得出结论,Android确实无法在任何简单的内部网络上解析主机名,除非对设备进行根认证。
因此,您(或者我的客户)需要重新配置SSL证书,以处理发送到主机名之外的IP地址或FQDN的请求。这可以通过将两者作为SAN(使用者备用名称)添加到证书来完成。
例如:
请注意"DNS名称"和"IP地址"报头之间的区别。可以想象,在某些边缘情况下,将IP地址添加为DNS名称也会有所帮助。
q8l4jmvw2#
实际上,您可以使用IP地址通过简单的http进行连接,并将其放在允许明文通信的清单中: