【问题标题】:Bypassing App Transport Security to allow unsecured HTTP server绕过应用程序传输安全以允许不安全的 HTTP 服务器
【发布时间】:2016-12-19 04:58:18
【问题描述】:

情况:

我必须连接到这两个不同的服务器以进行开发和登台使用。两台服务器都有不受信任的 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 用于我的网络层,它基本上只是Alamofire 的一个很好的包装器。如需更多信息,我使用XCode 7.3,该应用仅支持> iOS 9

我做了什么:

我非常了解 Apple 想要强制执行的应用程序传输安全问题。我想禁用它以进行开发,但仍然是徒劳的。我尝试绕过 ATS 的一些方法如下:

  1. 在我的plist 中添加以下内容以允许任意加载。

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    
  2. 明确定义域异常。

    <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 的屏幕截图:

  1. 我还尝试禁用 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)
    
  2. 打开 URL 并在我的设备和模拟器上下载证书。

即使经过上述所有步骤,我仍然遇到同样的错误。关于我做错了什么以及我能做些什么来解决这个问题?顺便说一句,如果我可以避免使用服务器端解决方案,那就太好了。

提前致谢。

参考资料:

【问题讨论】:

  • 您试图从 plist 中删除所有例外域字段,只留下 NSAllowsArbitraryLoads ?

标签: swift ios9 alamofire app-transport-security moya


【解决方案1】:

仅使用主机名定义您的策略。

// Disable Policies
let policies: [String: ServerTrustPolicy] = [
    "example.entrydns.org": .DisableEvaluation
]

【讨论】:

    【解决方案2】:

    我将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
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 2011-05-04
      • 2021-07-30
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多