2016-10-22 22 views
2

私はサーバーへのポストコールを作成していますが、サーバー証明書が無効であるというエラーが続いていましたので、調査した後、これは完全にうまくいく(私は認証の挑戦をプリントしてそれを確認する)が、コールの残りの部分は通過せず、私のサーバーから情報を得ることができない、認証チャレンジの後に何も起こらない、通常は返されるデータ。しかし、何も起こりませんし、私のurlsessiondatadelegatesのどれも呼ばれません(休憩でチェック)。URLSessionデリゲートは認証チャレンジ後に呼び出されません

誰でもその理由を特定できますか?コード:

var request = URLRequest(url: URL(string: "https://45.56.105.97:7915/search-v2")!) 
request.httpMethod = "POST" 
request.addValue("Basic ***********", forHTTPHeaderField: "Authorization") 

let task = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main) 
      task.dataTask(with: request) { (data, response, error) in 
       print(error) 
       print(data) 
       if let responseData = NSString(data: data!, encoding: String.Encoding.utf8.rawValue){ 
            print("data: \(responseData)") 
            self.parseXML(data!) 

           } 
     }.resume() 

デリゲートメソッド:実行した後

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { 
    print("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)") 

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { 
     print("send credential Server Trust") 
     let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) 
     challenge.sender!.use(credential, for: challenge) 

    }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{ 
     print("send credential HTTP Basic") 
     let defaultCredentials: URLCredential = URLCredential(user: "username", password: "password", persistence:URLCredential.Persistence.forSession) 
     challenge.sender!.use(defaultCredentials, for: challenge) 

    }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{ 
     print("send credential NTLM") 

    } else{ 
     challenge.sender!.performDefaultHandling!(for: challenge) 
    } 

} 
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { 
    print("Data received: \(data)") 
} 

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { 

    print("Response received: \(response)") 
} 

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { 
    print("something went wrong: \(error)") 
} 

func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { 
    print("rep: \(response)") 
} 

、私が印刷されますすべてがある:autherntcationchallenge = NSURLAuthenticationMethodServerTrust 私も見てきた信用証明書サーバのトラスト

送りましたどのようにデータを取得するためのクロージャーメソッドまたはデリゲートメソッドのみを使用することができるかについての会話/両方ではありません。私は成功なしですべてを試しました。

**また、私は盲目的にサーバーを信頼するべきではないことを知っていますが、データを受信できない理由を理解しようとしています。これは重大なセキュリティ上の欠陥があることを認識しています。

+1

これらのデリゲートメソッドが完了ハンドラを提供するときは、その完了ハンドラを呼び出す必要があり、または他の接続は進まないだろう。 – Rob

+0

"urlsessiondatadelegates"が呼び出されたかどうかは、呼び出されたらコードを共有してください? –

答えて

3

二つの問題があります。

  • ロブはすでにコメントで述べたように、あなたのデリゲートメソッドのいずれかで完了ハンドラを呼び出すされていませんが。これは、接続がその時点で進行を停止することを意味します。
  • チャレンジ送信者のメソッドを呼び出してクレデンシャルを提供しています。それはNSURLConnectionで動作しますが、NSURLSessionでは補完ハンドラを呼び出す必要があります。さもなければ、物事は非常にひどく壊れます。

    completionHandler(.PerformDefaultHandling, nil) 
    
+0

あなたが提案したものを試しましたが、実際に完了ハンドラが呼び出されますが、次のエラーが発生します。このサーバーの証明書が無効です。 _________________のように思われるサーバーに接続している可能性があります。これは、認証チャレンジデリゲートメソッドを含めるように促したのと同じエラーでした。 –

+0

これは、サーバー証明書が無効なためです。あなたが解決する方法は、他の方法で証明書を検証することです(たとえば、公開鍵が予期しているものであるかどうかを確認するか、保護スペースを変更して別のルート/アンカー証明書を許可し、証明書の有効性を再確認します)、その検証に合格すると、デフォルトの処理を実行する代わりに、提供された証明書を使用するように指示します。いずれにしても、チャレンジ送信者のメソッドを呼び出すことはどんな場合でも正しいことをしないため、補完ハンドラを呼び出すことで行います。 :-) – dgatwood

+1

このようなメソッドを書く方法の追加の背景については、https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.htmlを読むことをお勧めします。最後に確認したのはObj-Cです。でも、これを安全に行うために使用できるさまざまなアプローチのアイデアは少なくともあなたに与えられます。 – dgatwood