I'm having troubles performing a HTTPS post request to my django rest api. I have django-sslserver running to expose the api on port 8000. Things seem fine, when I make a request in a browser https://server-ip-addr:8000/api_view/
my browser complains "Hey! This guys certificate is self signed!" I say "yeah I know, that's me" and continue into the dangerous response.
Anyways I'm attempting to perform the same in Swift for an iOS application. I've found from this link here on implementing NSURLSession
delegate protocols/functions NSURLSessionDelegate.URLSession()
and NSURLSessionTaskDelegate.URLSession()
. I've tweaked the example so that it atomically performs login attempts to my sslserver.
I've done so in the following code, a class implementing the two protocols above designed to pass username/password credentials to the server and wait for a response.
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)
}
}
So I go to attempt to perform the attemptLogin()
function, providing the simple callback function to confirm a response
var gatekeeper = SecureLogin()
gatekeeper.attemptLogin(username, password: password, callback: {data, response, error -> Void in
println("inside gatekeeper")
}
println("beginning wait")
sleep(25)
I sleep the thread 25 seconds to keep the process alive long enough for the response to come in.
The output on the console looks like:
inside attempt login
beginning wait
Then the program dies, no response/"inside gatekeeper" message received, my django server terminal doesn't show any received requests either. I ran a sanity check: I've commented out the implementations of the delegate methods and the server receives the request, responds with:
inside attempt login
beginning wait
2015-01-27 11:29:37.192 LdapAuthSecure[12783:1475994] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9812)
the expected error when there is no protocol for handling an authorization challenge.
Can anyone spot any problems with my implementation of the NSURLSession or its delegates? I find it very strange that the request doesn't even reach the server. Thank you for any help!