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

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

我在对我的 django rest api 执行 HTTPS post 请求时遇到问题。我运行 django-sslserver 以在端口 8000 上公开 api。当我在浏览器 https://server-ip-addr:8000/api_view/ 中发出请求时,一切似乎都很好我的浏览器提示“咦!这家伙的证书是自签名的!”我说“是的,我知道,那就是我”,然后继续做出危险的 react 。

无论如何,我正尝试在 Swift 中为 iOS 应用程序执行相同的操作。我从这个 link here 中找到了关于实现 NSURLSession 委托(delegate)协议(protocol)/函数 NSURLSessionDelegate.URLSession()NSURLSessionTaskDelegate.URLSession()。我已经调整了示例,以便它自动执行对我的 sslserver 的登录尝试。

我在下面的代码中这样做了,一个类实现了上面的两个协议(protocol),旨在将用户名/密码凭证传递给服务器并等待响应。

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 秒,以使进程保持事件状态足够长的时间,以便响应进入。

控制台输出如下:

inside attempt login

beginning wait

然后程序终止,没有收到响应/“内部网守”消息,我的 django 服务器终端也没有显示任何收到的请求。我运行了完整性检查:我注释掉了委托(delegate)方法的实现,服务器收到请求,响应:

inside attempt login

beginning wait

2015-01-27 11:29:37.192 LdapAuthSecure[12783:1475994] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9812)

没有处理授权挑战的协议(protocol)时的预期错误。

任何人都可以发现我的 NSURLSession 或其委托(delegate)的实现有任何问题吗?我觉得很奇怪,请求甚至没有到达服务器。感谢您的帮助!

最佳答案

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

关于Swift NSURLSession HTTPS 自签名 - 请求永远不会到达服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28178537/

相关文章:

tomcat - Apache tomcat 相互认证自签名证书 REST 服务

node.js - express 4 中的 HTTPS

django - 在 django Rest Framework One 旁边使用我自己的模板来上传文件

python - 如何动态更改 Django Rest Framework 嵌套序列化程序的深度?

django - 如何将 serializers.RelatedField() 添加到 django rest 框架中的 Meta 类字段

swift - Swift 惰性公共(public) var 初始化中的无主 self 会发出编译器错误,但私有(private) var 初始化则不会

swift - 如何声明以函数为值并以整数为键的字典?

ios - swift : View's frame getting altered when a subview is added

ios - 推送通知 - 使用 SceneDelegate 在通知点击时推送 ViewController

php - Chrome : Google Maps API JS Loading Issue with https