Authentication Swift 3 NTLM认证

Authentication Swift 3 NTLM认证,authentication,soap,swift3,odata,ntlm,Authentication,Soap,Swift3,Odata,Ntlm,在最近的一个项目中,我试图分别以SOAP和oData格式从服务器中提取一些数据,这些数据受到Microsoft NTLM身份验证的保护,而弄明白如何做是一场噩梦,没有一个在线示例真正起作用。因此,这是我的解决方案;我不得不调整、扩展和合并一些不同的来源。我希望这对将来的人有所帮助 // // ViewController.swift // ntlm // // Created by Kamik423 on 21.3.17. // Copyright © 2017 Kamik423 All

在最近的一个项目中,我试图分别以SOAP和oData格式从服务器中提取一些数据,这些数据受到Microsoft NTLM身份验证的保护,而弄明白如何做是一场噩梦,没有一个在线示例真正起作用。

因此,这是我的解决方案;我不得不调整、扩展和合并一些不同的来源。我希望这对将来的人有所帮助

//
//  ViewController.swift
//  ntlm
//
//  Created by Kamik423 on 21.3.17.
//  Copyright © 2017 Kamik423 All rights reserved.
//
// You might have to allow arbitrary loads!!
//
//  Adapted from:
//      https://gist.github.com/stevenschobert/f374c999e5cba6ccf09653b846967c83
//      https://blogs.msdn.microsoft.com/chiranth/2013/09/20/ntlm-want-to-know-how-it-works/

import UIKit

class ViewController: UIViewController {

    var username: String? = nil
    var password: String? = nil

    lazy var conn: URLSession = {
        let config = URLSessionConfiguration.ephemeral
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
        return session
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        username = "<username>"
        password = "<password>"
        ntlm()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func ntlm() {
        let urlString = "<url>"
        let url = URL(string: urlString)
        let request = NSMutableURLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60000)
        request.httpMethod = "GET"
        let task = conn.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            print(response)
            print(error)
            print(String(data: data!, encoding: .utf8))
        })
        task.resume()
    }

    func doesHaveCredentials() -> Bool {
        guard let _ = self.username else { return false }
        guard let _ = self.password else { return false }
        return true
    }
}

extension ViewController: URLSessionDelegate {

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        print("got challenge")

        guard challenge.previousFailureCount == 0 else {
            print("too many failures")
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM else {
            print("unknown authentication method \(challenge.protectionSpace.authenticationMethod)")
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        guard self.doesHaveCredentials() else {
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            DispatchQueue.main.async {
                print("Userdata not set")
            };
            return
        }

        let credentials = URLCredential(user: self.username!, password: self.password!, persistence: .forSession)
        challenge.sender?.use(credentials, for: challenge)
        completionHandler(.useCredential, credentials)
    }
}

这就是我的解决方案;我不得不调整、扩展和合并一些不同的来源。我希望这对将来的人有所帮助

//
//  ViewController.swift
//  ntlm
//
//  Created by Kamik423 on 21.3.17.
//  Copyright © 2017 Kamik423 All rights reserved.
//
// You might have to allow arbitrary loads!!
//
//  Adapted from:
//      https://gist.github.com/stevenschobert/f374c999e5cba6ccf09653b846967c83
//      https://blogs.msdn.microsoft.com/chiranth/2013/09/20/ntlm-want-to-know-how-it-works/

import UIKit

class ViewController: UIViewController {

    var username: String? = nil
    var password: String? = nil

    lazy var conn: URLSession = {
        let config = URLSessionConfiguration.ephemeral
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
        return session
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        username = "<username>"
        password = "<password>"
        ntlm()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func ntlm() {
        let urlString = "<url>"
        let url = URL(string: urlString)
        let request = NSMutableURLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60000)
        request.httpMethod = "GET"
        let task = conn.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            print(response)
            print(error)
            print(String(data: data!, encoding: .utf8))
        })
        task.resume()
    }

    func doesHaveCredentials() -> Bool {
        guard let _ = self.username else { return false }
        guard let _ = self.password else { return false }
        return true
    }
}

extension ViewController: URLSessionDelegate {

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        print("got challenge")

        guard challenge.previousFailureCount == 0 else {
            print("too many failures")
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM else {
            print("unknown authentication method \(challenge.protectionSpace.authenticationMethod)")
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        guard self.doesHaveCredentials() else {
            challenge.sender?.cancel(challenge)
            completionHandler(.cancelAuthenticationChallenge, nil)
            DispatchQueue.main.async {
                print("Userdata not set")
            };
            return
        }

        let credentials = URLCredential(user: self.username!, password: self.password!, persistence: .forSession)
        challenge.sender?.use(credentials, for: challenge)
        completionHandler(.useCredential, credentials)
    }
}

对于Alamofire:请检查我的增强答案:对于Alamofire:请检查我的增强答案: