Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenschobert/f374c999e5cba6ccf09653b846967c83 to your computer and use it in GitHub Desktop.
Save stevenschobert/f374c999e5cba6ccf09653b846967c83 to your computer and use it in GitHub Desktop.
Example of NTLM authentication in iOS using NSURLSession
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")
}
}
@kpostekk
Copy link

Thank you for this gist. It really helped me a lot and saved me a few hours :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment