绕过 App Transport Security 以允许不安全的 HTTP 服务器
Bypassing App Transport Security to allow unsecured HTTP server
情况:
我必须连接到这两个不同的服务器以供开发和暂存使用。两台服务器都具有不受信任的 SSL 证书。
出于示例目的,这两个服务器 URL 是:
暂存服务器:https://52.70.13.2:1010/
开发服务器:https://example.entrydns.org:1012
每当我尝试调用 API 时,我都会收到以下错误的空响应:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
或者有时,
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
我用Moya for my network layers, which is basically just a nice wrapper for Alamofire。有关其他信息,我使用 XCode 7.3
并且该应用仅支持 > iOS 9
.
我做了什么:
我非常清楚 Apple 想要强制执行的应用程序传输安全问题。我想禁用它进行开发,但仍然是徒劳的。我尝试绕过 ATS 的一些方法如下:
在我的 plist
中添加以下内容以允许任意加载。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
明确定义域例外。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>example.entrydns.org</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
这是我的 plist
的屏幕截图:
我还尝试禁用 Alamofire 管理器共享实例的服务器信任策略。这是示例代码:
// Disable Policies
let policies: [String: ServerTrustPolicy] = [
"https://example.entrydns.org:1012/": .DisableEvaluation,
"https://52.70.13.2:1010/": .DisableEvaluation
]
let manager = Manager(
configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
)
// ---------------
let networkLogger = NetworkLoggerPlugin(verbose: true, responseDataFormatter: nil)
let endpointClosure = { (target: ExampleAPI) -> Endpoint<ExampleAPI> in
let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
let endpoint: Endpoint<ExampleAPI> = Endpoint<ExampleAPI>
(URL: url,
sampleResponseClosure: {.NetworkResponse(200, target.sampleData)},
method: target.method,
parameters: target.parameters,
parameterEncoding: .URLEncodedInURL)
return endpoint.endpointByAddingHTTPHeaderFields(target.header())
}
let ExampleProvider = MoyaProvider<ExampleAPI>(manager: manager,
plugins:[networkLogger],
endpointClosure: endpointClosure)
打开 URLs 并在我的设备和模拟器上下载证书。
即使完成上述所有步骤,我仍然遇到相同的错误。任何关于我做错了什么以及我能做些什么来解决这个问题的看法?顺便说一句,如果我能避免服务器端解决方案那就太好了。
提前致谢。
参考文献:
仅使用主机名定义策略。
// Disable Policies
let policies: [String: ServerTrustPolicy] = [
"example.entrydns.org": .DisableEvaluation
]
我将 ServerTrustPolicyManager
子类化以处理自签名 https 认证。
internal class MyServerTrustPolicyManager: ServerTrustPolicyManager {
// In order to trust all self-signed https certifications.
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
}
}
然后,使用上面的 ServerTrustPolicyManager
.
创建自定义 SessionManager
// Create a `SessionManager` of Alamofire based on custom trust policy manager
func getHttpManager(timeout: TimeInterval) -> SessionManager {
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = timeout
sessionConfig.timeoutIntervalForResource = timeout
sessionConfig.requestCachePolicy = .reloadIgnoringLocalCacheData
sessionConfig.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
// Use customize policy
let trustPolicies = MyServerTrustPolicyManager(policies: [:])
let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)
return manager
}
情况:
我必须连接到这两个不同的服务器以供开发和暂存使用。两台服务器都具有不受信任的 SSL 证书。 出于示例目的,这两个服务器 URL 是:
暂存服务器:https://52.70.13.2:1010/
开发服务器:https://example.entrydns.org:1012
每当我尝试调用 API 时,我都会收到以下错误的空响应:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
或者有时,
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
我用Moya for my network layers, which is basically just a nice wrapper for Alamofire。有关其他信息,我使用 XCode 7.3
并且该应用仅支持 > iOS 9
.
我做了什么:
我非常清楚 Apple 想要强制执行的应用程序传输安全问题。我想禁用它进行开发,但仍然是徒劳的。我尝试绕过 ATS 的一些方法如下:
在我的
plist
中添加以下内容以允许任意加载。<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
明确定义域例外。
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>example.entrydns.org</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key> <false/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <true/> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> <key>NSRequiresCertificateTransparency</key> <false/> </dict> </dict> </dict>
这是我的 plist
的屏幕截图:
我还尝试禁用 Alamofire 管理器共享实例的服务器信任策略。这是示例代码:
// Disable Policies let policies: [String: ServerTrustPolicy] = [ "https://example.entrydns.org:1012/": .DisableEvaluation, "https://52.70.13.2:1010/": .DisableEvaluation ] let manager = Manager( configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies) ) // --------------- let networkLogger = NetworkLoggerPlugin(verbose: true, responseDataFormatter: nil) let endpointClosure = { (target: ExampleAPI) -> Endpoint<ExampleAPI> in let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString let endpoint: Endpoint<ExampleAPI> = Endpoint<ExampleAPI> (URL: url, sampleResponseClosure: {.NetworkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters, parameterEncoding: .URLEncodedInURL) return endpoint.endpointByAddingHTTPHeaderFields(target.header()) } let ExampleProvider = MoyaProvider<ExampleAPI>(manager: manager, plugins:[networkLogger], endpointClosure: endpointClosure)
打开 URLs 并在我的设备和模拟器上下载证书。
即使完成上述所有步骤,我仍然遇到相同的错误。任何关于我做错了什么以及我能做些什么来解决这个问题的看法?顺便说一句,如果我能避免服务器端解决方案那就太好了。
提前致谢。
参考文献:
仅使用主机名定义策略。
// Disable Policies
let policies: [String: ServerTrustPolicy] = [
"example.entrydns.org": .DisableEvaluation
]
我将 ServerTrustPolicyManager
子类化以处理自签名 https 认证。
internal class MyServerTrustPolicyManager: ServerTrustPolicyManager {
// In order to trust all self-signed https certifications.
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
}
}
然后,使用上面的 ServerTrustPolicyManager
.
SessionManager
// Create a `SessionManager` of Alamofire based on custom trust policy manager
func getHttpManager(timeout: TimeInterval) -> SessionManager {
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = timeout
sessionConfig.timeoutIntervalForResource = timeout
sessionConfig.requestCachePolicy = .reloadIgnoringLocalCacheData
sessionConfig.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
// Use customize policy
let trustPolicies = MyServerTrustPolicyManager(policies: [:])
let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)
return manager
}