Swift - аутентификация дайджеста HTTP - PullRequest
0 голосов
/ 29 мая 2020

В настоящее время я нахожусь в процессе реинжиниринга API домашней автоматизации. Я хочу управлять всеми настройками с помощью моего собственного приложения, потому что на самом деле нет текущего приложения для домашней автоматизации от компании.

В любом случае - я уже выполнил аутентификацию с помощью своего устройства SmartHome . Чтобы не усложнять: мне нужно http-дайджест-аутентификация для окончательного общения. Я уже смог подключиться к своему устройству через командную строку с помощью curl - к сожалению, это не работает в Swift, как планировалось.

curl -X POST -d '{"key": "value"}' https://192.168.0.0:1/action -k -s --digest --user username:password

Переведено на Swift:

(1) Использование Alamofire

import Alamofire
let data: [String: any] = ["key": "value"]
let request = Alamofire.request("https://192.168.0.0:1/action", method: HTTPMethod.post, parameters: data);
request.authenticate(user: "username", password: "password")
request.responseJSON { response in
    // leads to error because of invalid self signed certificate of the smart home device ("https:")
}

Примечание для Alamofire: я предполагаю, что использование внешней библиотеки, такой как AF, мало что дает смысл в этом случае - есть некоторые нерешенные проблемы, которые не позволяют работать такому коду, как указано выше. (Самоподписанные сертификаты создают проблемы, использование пользовательских экземпляров диспетчера, переопределяющих внутренние данные, также приводит к проблемам) - Я уже потратил часы, поверьте мне.

(2) Использование not Alamofire:)

extension ViewController: URLSessionDelegate {
    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        completionHandler(.useCredential, urlCredential)
    }
}



let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")

do {
    let jsonData = try JSONSerialization.data(withJSONObject: data, options: .prettyPrinted)
    request.httpBody = jsonData;
    let task = session.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            return
        }
        let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
        if let responseJSON = responseJSON as? [String: Any] {
        // success
        }
    }
    task.resume()
} catch { }

Похоже, что приведенный выше код работает нормально - проблема в том, что я еще не реализовал дайджест-аутентификацию - потому что я не нашел способа, как это сделать.

Было бы очень полезно, если бы кто-нибудь получите несколько советов, как сгенерировать заголовок Auth на основе имени пользователя и пароля

Edit

Curl использует этот Authorization header:

> Digest username="username", 
realm="XTV", 
nonce="MTU5MDcNc2UxNjQ3OTo1YzMwYjc3YjIxMzAAAGQ5Nzg2NzUzMmRkZGU1ZVVlYw==", 
uri="/action", 
cnonce="MTExOTZlZmI1MjBlYWU0MTIzMDBmNDE0YTkWzJl1MDk=", 
nc=00000001, 
qop=auth, 
response="2ba89269645e2aa24ac6f117d85e190c", 
algorithm="MD5"

Есть ли возможность сгенерировать этот заголовок в Swift?

1 Ответ

0 голосов
/ 29 мая 2020

Дайджест-аутентификация поддерживается автоматически URLSession и Alamofire через URLCredential (это то, что authenticate() использует в Alamofire), когда сервер правильно возвращает заголовок WWW-Authenticate с правильными настройками дайджеста.

Вы можете сгенерировать заголовок вручную, хотя я бы не рекомендовал это из-за сложности процесса дайджеста. Я обнаружил, что страница википедии достаточно тщательна, чтобы реализовать стандарт вручную.

...