【问题标题】:Swift NSURLSession HTTPS Self Sign - Request never reaches serverSwift NSURLSession HTTPS 自签名 - 请求永远不会到达服务器
【发布时间】:2015-01-27 19:34:52
【问题描述】:

我在对我的 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 秒,以使进程保持足够长的时间以响应进来。

控制台上的输出如下:

内部尝试登录

开始等待

然后程序终止,没有收到响应/“内部看门人”消息,我的 django 服务器终端也没有显示任何收到的请求。我进行了健全性检查:我已经注释掉了委托方法的实现,服务器接收到请求,响应:

内部尝试登录

开始等待

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      所以我从来没有为 iOS 编写过代码,但我从记忆中知道原生应用默认不会弹出对话框,也不会接受自签名证书。

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2020-03-26
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多