Swift NSURLSession HTTPS自签名 - 请求永远不会到达服务器

时间:2015-01-27 19:34:53

标签: swift https django-rest-framework nsurlsession self-signed

我在向django rest api执行HTTPS发布请求时遇到了麻烦。我运行django-sslserver来暴露端口8000上的api。事情看起来很好,当我在浏览器中发出请求时https://server-ip-addr:8000/api_view/我的浏览器抱怨"嘿!这个家伙证书是自签名的!"我说"是的,我知道,那是我"并继续进入危险的反应。

无论如何,我试图在Swift中为iOS应用程序执行相同的操作。我在此link here中找到了有关实施NSURLSession委托协议/功能NSURLSessionDelegate.URLSession()NSURLSessionTaskDelegate.URLSession()的信息。我已经调整了这个示例,以便它以原子方式对我的sslserver执行登录尝试。

我已经在以下代码中完成了这一操作,这是一个实现上述两种协议的类,旨在将用户名/密码凭据传递给服务器并等待响应。

class SecureLogin: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate {

    func attemptLogin(username: String, password: String,
        callback: ((NSData!,NSURLResponse!,NSError!) -> Void)?) {

            println("inside attempt login")

            var request = NSMutableURLRequest(URL: NSURL(string: "https://147.222.164.91:8000/ldapauth/")!)
            request.HTTPMethod = "POST"


            var params = ["username":username, "password":password] as Dictionary<String, String>

            var err: NSError?
            request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")

            var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
            var session = NSURLSession(configuration: configuration,
                delegate: self,
                delegateQueue:NSOperationQueue.mainQueue())
            var task = session.dataTaskWithRequest(request,callback)

            task.resume()
    }

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

    func URLSession(session: NSURLSession,
        task: NSURLSessionTask,
        willPerformHTTPRedirection response: NSHTTPURLResponse,
        newRequest request: NSURLRequest,
        completionHandler: (NSURLRequest!) -> Void) {
            println("Redirection received")
            var newRequest : NSURLRequest? = request
            println(newRequest?.description)
            completionHandler(newRequest)
    }
}

所以我去尝试执行attemptLogin()函数,提供简单的回调函数来确认响应

var gatekeeper = SecureLogin()

gatekeeper.attemptLogin(username, password: password, callback: {data, response, error -> Void in

    println("inside gatekeeper")

}

println("beginning wait")

sleep(25)

我将线程休眠25秒以使进程保持足够长的时间以便响应进入。

控制台上的输出如下所示:

  

内部尝试登录

     

开始等待

然后程序死了,没有响应/&#34;在网守内部&#34;收到的消息,我的django服务器终端也没有显示任何收到的请求。我运行了一个完整性检查:我已经注释掉了委托方法的实现,服务器收到了请求,并回复:

  

内部尝试登录

     

开始等待

     

2015-01-27 11:29:37.192 LdapAuthSecure [12783:1475994] NSURLConnection / CFURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9812)

没有处理授权质询的协议时的预期错误。

任何人都可以发现我执行NSURLSession或其代理的任何问题吗?我发现这个请求甚至无法到达服务器,这一点非常奇怪。谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

如果这是iOS 9,并且您针对iOS 9(或更高版本)SDK构建了应用程序,那么您还必须调整Info.plist文件以告知它允许不安全的加载。否则,URL加载系统不会调用您的身份验证处理程序。

答案 1 :(得分:-1)

所以我从来没有为iOS编码,但我确实从内存中知道原生应用程序默认不会弹出对话框也不接受自签名证书。

如果您拥有某个域名(如果没有,则可能更容易),您可以从https://www.startssl.com/https://buy.wosign.com/free/获得免费证书

或者您可以通过将自签名证书通过电子邮件发送到手机然后再打开来安装。

您可以从“设置”中的配置文件页面中删除自签名证书。

我也找到了这个答案:https://stackoverflow.com/a/22674004/4837003 但这看起来会禁用验证。