背景

最近App似乎有报异常是DNS无法解析,尝试解决此问题.搜集到的资料很少,甚至连AFN原作者都判定这可能是一个无解的问题,参见: https://github.com/AFNetworking/AFNetworking/issues/2954,不过最终还是靠着stackoverflow上的一丁点提示,顺利找到并汇集成了一个可用的解决方案.大喜,与君共享!

问题描述

通过IP直接访问网站,可以解决DNS劫持问题.DNS劫持,可以通过修改电脑的host文件模拟.如果是HTTP请求,使用ip地址直接访问接口,配合header中Host字段带上原来的域名信息即可;如果是 https请求,会很麻烦,需要 Overriding TLS Chain Validation Correctly;curl 中有一个 -resolve 方法可以实现使用指定ip访问https网站,iOS中集成curl库应该也可以,不过改动太大,未验证;对于服务器IP经常变的情况,可能需要使用httpDNS服务,参见:https://www.dnspod.cn/httpdns.

解决方案讨论

1. 最直接的方式是允许无效的SSL证书,生产环境不建议使用;

2.一个需要部分重写AFN源码的方法.

  • 在Info.plist中添加NSAppTransportSecurity类型Dictionary,在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES.这些本来是用来解决iOS9下,允许HTTP请求访问网络的,当然作用不止这些.具体原因感兴趣的自行google.

  • 给 AFURLConnectionOperation 类添加新属性:

/** 可信任的域名,用于支持通过ip访问此域名下的https链接.
Trusted domain, this domain for support via IP access HTTPS links.
*/
@property(nonatomic, strong) NSMutableArray * trustHostnames;
  • 给 AFURLConnectionOperation 实现的代理方法: - (void)connection:(NSURLConnection *)connection

    willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 添加添加可信任的域名的相关逻辑代码:
- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if (self.authenticationChallenge) {
self.authenticationChallenge(connection, challenge);
return;
} if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; /* 添加可信任的域名,以支持:直接使用ip访问特定https服务器.
Add trusted domain name to support: direct use of IP access specific HTTPS server.*/
for (NSString * trustHostname in [self trustHostnames]) {
serverTrust = AFChangeHostForTrust(serverTrust, trustHostname);
} ....
  • 参考Apple官方文档,实现自定义的添加可信域名的函数: AFChangeHostForTrust
static inline SecTrustRef AFChangeHostForTrust(SecTrustRef trust, NSString * trustHostname)
{
if ( ! trustHostname || [trustHostname isEqualToString:@""]) {
return trust;
} CFMutableArrayRef newTrustPolicies = CFArrayCreateMutable(
kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, (CFStringRef)trustHostname); CFArrayAppendValue(newTrustPolicies, sslPolicy); #ifdef MAC_BACKWARDS_COMPATIBILITY
/* This technique works in OS X (v10.5 and later) */ SecTrustSetPolicies(trust, newTrustPolicies);
CFRelease(oldTrustPolicies); return trust;
#else
/* This technique works in iOS 2 and later, or
OS X v10.7 and later */ CFMutableArrayRef certificates = CFArrayCreateMutable(
kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); /* Copy the certificates from the original trust object */
CFIndex count = SecTrustGetCertificateCount(trust);
CFIndex i=0;
for (i = 0; i < count; i++) {
SecCertificateRef item = SecTrustGetCertificateAtIndex(trust, i);
CFArrayAppendValue(certificates, item);
} /* Create a new trust object */
SecTrustRef newtrust = NULL;
if (SecTrustCreateWithCertificates(certificates, newTrustPolicies, &newtrust) != errSecSuccess) {
/* Probably a good spot to log something. */ return NULL;
} return newtrust;
#endif
}
  • 使用AOP方法,重写 AFURLConnectionOperation 的trustHostnames属性:
    /* 使用AOP方式,指定可信任的域名, 以支持:直接使用ip访问特定https服务器.*/
[AFURLConnectionOperation aspect_hookSelector:@selector(trustHostnames) withOptions:AspectPositionInstead usingBlock: ^(id<AspectInfo> info){
__autoreleasing NSArray * trustHostnames = @[@"www.example.com"]; NSInvocation *invocation = info.originalInvocation;
[invocation setReturnValue:&trustHostnames];
}error:NULL];

此处用到的是一个 iOS AOP库,不熟悉的点这里: http://www.ios122.com/2015/08/aspects/.

AFNetworking 原作者都无法解决的问题: 如何使用ip直接访问https网站?的更多相关文章

  1. 解决python2.7.9以下版本requests访问https的问题

    在python2.7.9以下版本requests访问https连接后,总会报一些关于SSL warning. 解决法子可以参考:https://urllib3.readthedocs.io/en/la ...

  2. ACME[free https] Linux中使用curl命令访问https站点4种常见错误和解决方法

    free https certification generator https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E 每一种客户 ...

  3. 解决Chrome浏览器访问https提示“您的连接不是私密连接”的问题

    安装fiddler后,使用Chrome访问https网站时,可能会出现以下错误,本文说明如何解决此类问题: “您的连接不是私密连接”.“NET::ERR_CERT_AUTHORITY_INVALID” ...

  4. 火狐浏览器 访问所有HTTPS网站显示连接不安全解决办法

    当 Firefox 连接到一个安全的网站时(网址最开始为“https://”),它必须确认该网站出具的证书有效且使用足够高的加密强度.如果证书无法通过验证,或加密强度过低,Firefox 会中止连接到 ...

  5. IIS中访问自己开发的Webservice site就自动停止,尝试重启IIS和重启服务器都不能解决。

    今天在加班的时候发现一个奇怪的问题,IIS里面我们自己开发的Webservice site一访问就自动停止.尝试重启IIS和重启服务器都不能解决.后台windows events报错信息是The Mo ...

  6. afnetworking NSCocoaErrorDomain Code=3840 解决

    afnetworking json解析出错 解决方法1 AFURLResponseSerialization.m 258行修改 responseString = [responseString str ...

  7. 解决linux部署项目后,第一次访问初始化数据源的时候很慢的问题

    先说一下场景 测试环境是linux - centos6.5,项目是分布式的,分别搭建到linux上 数据货使用的是阿里巴巴数据源 每次重启后的第一次访问会比较慢,查看日志发现 卡在这个地方 ...{d ...

  8. WCF服务发布到IIS时候,只能根据hostname访问,不能根据IP地址访问的解决办法

    本文转载:http://www.cnblogs.com/deerbox/archive/2013/05/13/3076248.html 环境: VS2010 sp1,.net framework 4. ...

  9. 源码编译安装 PHP5.5.0,解决curl_exec访问HTTPS返回502错误的问题(修改PATH路径)

    最近碰到一个奇怪的问题, PHP使用 curl_exec 访问 HTTPS 网页时, 返回502错误, 访问HTTP网页时没有问题,  用   echo   phpinfo() ;  查看, 支持op ...

随机推荐

  1. set global show_compatibility_56 = on;永久生效MySQL重启

    1. 找到MySQL的配置文件,一般在MySQL的安装目录下,例如我的: C:\Program Files\MySQL\MySQL Server 5.7 ,打开下面的一个配置文件: my-defaul ...

  2. [leetcode]Find Minimum in Rotated Sorted Array @ Python

    原题地址:https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array/ 解题思路:话说leetcode上面的二分查找题目 ...

  3. Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  4. Scala 深入浅出实战经典 第48讲:Scala类型约束代码实战及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  5. C# Activex开发、打包、签名、发布 C# Activex开发、打包、签名、发布 [转]

    C# Activex开发.打包.签名.发布 2013-06-22 12:01:20 浏览:3823 一.前言 最近有这样一个需求,需要在网页上面启动客户端的软件,软件之间的通信.调用,单单依靠HTML ...

  6. [转]Linux下的lds链接脚本详解

    转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml     一. 概论 每一个链接过程都由链接脚本(lin ...

  7. Hadoop - Azkaban 作业调度

    1.概述 在调度 Hadoop 的相关作业时,有以下几种方式: 基于 Linux 系统级别的 Crontab. Java 应用级别的 Quartz. 第三方的调度系统. 自行开发 Hadoop 应用调 ...

  8. 不同iOS版本做代码适配__IPHONE_OS_VERSION_MAX_ALLOWED 和 __IPHONE_8_0等专业术语

    目前开发只想最低版本支持iOS8了,iOS8以前的就不管了,然后现在iOS9和iOS10出来以后,有些新的API,也有些弃用的API,为了兼容,有时候代码里面需要编写判断不同iOS版本,或者只允许指定 ...

  9. Session机制详解

    转自:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能 ...

  10. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...