Created
June 17, 2016 14:00
-
-
Save stevenschobert/f374c999e5cba6ccf09653b846967c83 to your computer and use it in GitHub Desktop.
Example of NTLM authentication in iOS using NSURLSession
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ViewController: UIViewController { | |
@IBOutlet weak var execButton: UIButton! | |
var username: String? = nil | |
var password: String? = nil | |
lazy var conn: NSURLSession = { | |
let config = NSURLSessionConfiguration.ephemeralSessionConfiguration() | |
let session = NSURLSession(configuration: config, delegate: self, delegateQueue: nil) | |
return session | |
}() | |
@IBAction func execButtonTapped(sender: UIButton) { | |
let url = NSURL(string: "http://somentlmurlc.om") | |
let request = NSMutableURLRequest(URL: url!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60000) | |
let body = "some body" | |
request.HTTPMethod = "POST" | |
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding) | |
let task = conn.dataTaskWithRequest(request) | |
task.resume() | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
override func didReceiveMemoryWarning() { | |
super.didReceiveMemoryWarning() | |
} | |
func login(username: String?, password: String?) { | |
self.username = username | |
self.password = password | |
} | |
func presentLogin() { | |
let alertView = UIAlertController(title: "Please login", message: "You need to provide credentials to make this call.", preferredStyle: .Alert) | |
let loginAction = UIAlertAction(title: "Login", style: .Default) { action in | |
let username = alertView.textFields![0] as UITextField | |
let password = alertView.textFields![1] as UITextField | |
self.login(username.text, password: password.text) | |
} | |
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { _ in } | |
alertView.addTextFieldWithConfigurationHandler { textField in | |
textField.placeholder = "Username" | |
} | |
alertView.addTextFieldWithConfigurationHandler { textField in | |
textField.placeholder = "Password" | |
textField.secureTextEntry = true | |
} | |
alertView.addAction(cancelAction) | |
alertView.addAction(loginAction) | |
self.presentViewController(alertView, animated: true, completion: {}) | |
} | |
func doesHaveCredentials() -> Bool { | |
guard let _ = self.username else { return false } | |
guard let _ = self.password else { return false } | |
return true | |
} | |
} | |
extension ViewController: NSURLSessionDelegate { | |
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { | |
print("got challenge") | |
guard challenge.previousFailureCount == 0 else { | |
print("too many failures") | |
self.username = nil | |
self.password = nil | |
challenge.sender?.cancelAuthenticationChallenge(challenge) | |
completionHandler(.CancelAuthenticationChallenge, nil) | |
return | |
} | |
guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM else { | |
print("unknown authentication method \(challenge.protectionSpace.authenticationMethod)") | |
challenge.sender?.cancelAuthenticationChallenge(challenge) | |
completionHandler(.CancelAuthenticationChallenge, nil) | |
return | |
} | |
guard self.doesHaveCredentials() else { | |
challenge.sender?.cancelAuthenticationChallenge(challenge) | |
completionHandler(.CancelAuthenticationChallenge, nil) | |
dispatch_async(dispatch_get_main_queue(), { | |
self.presentLogin() | |
}) | |
return | |
} | |
let credentials = NSURLCredential(user: self.username!, password: self.password!, persistence: .ForSession) | |
challenge.sender?.useCredential(credentials, forAuthenticationChallenge: challenge) | |
completionHandler(.UseCredential, credentials) | |
} | |
} | |
extension ViewController: NSURLSessionDataDelegate { | |
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { | |
guard let httpResponse = response as? NSHTTPURLResponse else { return } | |
print(httpResponse.description) | |
} | |
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { | |
print("done with error") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this gist. It really helped me a lot and saved me a few hours :D