我正在尝试使用https安全连接调用本地网络上托管的Web服务,首先它提供了HostNameUnresolved
的异常,所以我使用了ip地址而不是名称,现在我收到以下错误:
Error in geting tags.=javax.net.ssl.SSLException: hostname in certificate didn't match: <10.100.248.99> !=
我已经将中间证书和根证书添加到了android可信列表中。
有人能给我一个解决方案,使用主机名而不是ip地址访问本地网络上安全托管的Web服务吗?
答案 0 :(得分:1)
我曾经在我的同事正在做的一个项目中看到类似的错误,我们发现的原因是,如果你试图从主ui线程进行网络调用,android系统会阻止它,尽管这个功能被引入到API之后就像以前一样工作正常。这样做是为了减少主ui线程的压力,所以我们创建了一个单独的服务,然后在其中我们提供了一个asynctask来进行网络调用。我不记得引入它的确切API级别,但你总是可以通过护目镜检查它,也可以通过你正在使用的API级别来检查它?
答案 1 :(得分:1)
正如其他人所说,您需要一些东西才能连接您的网络服务:
- 模拟器知道您需要连接的服务器的IP地址是什么
- 通过HTTPS连接的服务器名称URL必须解析为SSL证书的域
要做到这一点,你需要:
writeable
从您的桌面shell(Linux的示例,但在Windows上类似,并假设在/android-sdk
上安装了Android sdk):
cd /android-sdk/tools/
./emulator -avd NexusS -partition-size 128
其中NexusS是您设备的AVD名称。您MUST
从命令行启动模拟器,否则您将在以后的步骤中收到错误。
现在打开另一个shell终端并获取你的模拟器/ system / etc / hosts文件:
cd /android-sdk/platform-tools
./adb remount
./adb pull /system/etc/hosts /tmp/
remount
是将分区设置为可写。上面的pull
命令会将主机文件复制到桌面的/tmp/hosts
从桌面编辑/ tmp / hosts文件以满足您的需要,即如果Web服务是https://www.example.com/foo且IP是192.168.1.10:
127.0.0.1 locahost
192.168.1.10 www.example.com
然后将其推回模拟器:
cd /android-sdk/platform-tools
./adb push /tmp/hosts /system/etc/
您现在应该可以连接到网络服务了。
请注意,如果是自签名证书,您仍可能会遇到错误。
下面的图片是在编辑hosts
文件之前:
编辑后:
答案 2 :(得分:1)
您应该使用 HostnameVerifier 来信任指定主机的Android。
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 30000);
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient httpClient = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(httpClient.getParams(), registry);
DefaultHttpClient client = new DefaultHttpClient(mgr, httpClient.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
现在执行您想要客户端对象的请求。