web-dev-qa-db-ja.com

iOS 7のNSURLSessionを使用して自己署名SSL証明書を受け入れる方法

次のコードがあります(Swift実装)。

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool
{
    return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
}

func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
{
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
    {

        if challenge.protectionSpace.Host == "myDomain"
        {
            let credentials = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
            challenge.sender.useCredential(credentials, forAuthenticationChallenge: challenge)
        }
    }

    challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)

}

IOS 8.xでは完全に機能しますただし、iOS 7.xでは機能しません iOS 7.xではエラーが発生します。

NSURLConnection/CFURLConnection HTTPロードに失敗しました(kCFStreamErrorDomainSSL、-9813)

何か案が?ありがとうございました!!!

15
Carlos Cardoso

両方とも connection:canAuthenticateAgainstProtectionSpace:およびconnection:didReceiveAuthenticationChallenge:はとにかくiOS 8では非推奨であるため、他の方法を使用する必要があります。

私のプロジェクトで使用しているのは、NSURLSessionDelegateのデリゲートメソッドです。そのプロトコルを遵守してから、このメソッドを追加します。

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}

次に、delegateをselfに設定してNSURLSessionを初期化します。例えば:

var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())

次に、そのセッションインスタンスを使用して、dataTaskWithRequestメソッドを呼び出します。

var task = session.dataTaskWithRequest(request){
    (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
    if error != nil {
        callback("", error.localizedDescription)
    } else {
        var result = NSString(data: data, encoding:
            NSASCIIStringEncoding)!
    }
}
task.resume()

完全な動作例は here にあります。

セキュリティ上の理由から、自己署名証明書を使用する場合は、公開キーのピン留めも実装することをお勧めします( https://Gist.github.com/edwardmp/df8517aa9f1752e7335

23
edwardmp

uRLSessionDelegateでクラスを継承する

セッションオブジェクトを作成する

let config = URLSessionConfiguration.default


let session = Foundation.URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)


 let task = session.dataTask(with: httpRequest as URLRequest, completionHandler: {requestData, response, errorData -> Void in

            if errorData == nil {

                dataCallback(requestData! as NSData)
            }
            else {

                let error = NSError(domain: "Err-1001", code: 11, userInfo:nil)
                failureCallback(error)
            }
        });

        task.resume() 

代理メソッドを追加

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive     challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
     completionHandler(
        .useCredential,
        URLCredential(trust: challenge.protectionSpace.serverTrust!))
 }

これをinfo.plistファイルに追加します

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xyc.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>
0
sagar gawande