Как сделать запрос NTML с Alamofire 4.0?

Это заголовки запроса:

    let headers: HTTPHeaders = [
        "Accept": "application/json",
        "username": "someUserName",
        "password": "aPasswordForSomeUserName"
    ]

Когда я делаю запрос с кодом ниже, он выдает "Мусор в конце". Тем не менее, когда я проверил ответ с парсером JSON онлайн. Это действительный JSON.

Alamofire.request("http://myserver/list.svc/random", headers: headers).responseJSON { response in
    print(response)
}

Я также попытался сделать запрос, как это:

Alamofire.request("http://myserver/list.svc/random", headers: headers).responseString { response in
    print(response)
}

Я получаю это сообщение в консоли: "401 НЕСАНКЦИОНИРОВАН".

Что я делаю неправильно? Я считаю, что при использовании responseJSON Завершение блока это не жалуется на Unauthorization, но жалуется на плохой JSON (или какой-то мусор).

PS Тот же запрос отлично работает с Advance Rest Client (расширение Chrome), а также в браузере Chrome.

1 ответ

Я не знаю, насколько это актуально для вас, но у меня есть рабочее решение, которое я опубликую для дальнейшего использования.

Итак, у меня было два вопроса. Первый из них заключается в том, что заголовок авторизации выпал из запроса, когда он был перенаправлен. Второй - NTLM-вызов с сервера, который не обрабатывается. Надеюсь, следующий код должен быть понятен самому себе:) Он предполагает, что вы сохраняете имя пользователя и пароль только в переменных name.

    let credentialData = "\(username):\(password)".data(using: String.Encoding.utf8)!
    let base64Credentials = credentialData.base64EncodedString(options: [])
    request.addValue("Basic \(base64Credentials)", forHTTPHeaderField: "Authorization")

    let manager = Alamofire.SessionManager.default
    let delegate: Alamofire.SessionDelegate = manager.delegate

    // This bit will re-add the auth headers for the redirected request
    delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
        var redirectedRequest = request

        if let originalRequest = task.originalRequest, let redirectheaders = originalRequest.allHTTPHeaderFields {
            if let authorizationHeaderValue = redirectheaders["Authorization"] {
                redirectedRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
            }
            if let contentTypeHeaderValue = redirectheaders["Content-Type"] {
                redirectedRequest.setValue(contentTypeHeaderValue, forHTTPHeaderField: "Content-Type")
            }
        }

        return redirectedRequest
    }

    // This bit looks at challenges received and applies the correct credentials
    delegate.taskDidReceiveChallenge = { session, task, challenge in
        var disposition: URLSession.AuthChallengeDisposition = .useCredential
        var credential: URLCredential = URLCredential()

        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM) {
            disposition = URLSession.AuthChallengeDisposition.useCredential
            credential = URLCredential(user: username, password: password, persistence: URLCredential.Persistence.forSession)
        }

        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
            disposition = URLSession.AuthChallengeDisposition.useCredential
            credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        }

        return(disposition, credential)
    }

    manager.request(request).responseData { (response) in
        // Handle response accordingly
    }

Надеюсь, это кому-нибудь поможет.

В Swift4.2

Аламофайр встроил NTLMподдержка авторизации. Вы можете сделать такой запрос

        let user = "YOUR_USER_NAME OR EMAIL"
        let password = "YOUR_PASSWORD"
        let url = "YOUR_API_URL"
        let credential = URLCredential(user: user, password: password, persistence: .forSession)
        //These headers are optional based on your api and your server.
        //There were required for me
        let headers = ["Accept": "application/json;odata=verbose",
                           "Content-type": "application/json;odata=verbose"]
        Alamofire.request(url, method: .get, headers: headers).authenticate(usingCredential: credential).responseJSON {
                (response) in
                switch response.result {
                case .success:
                    if let value = response.result.value {
                        print("The server response is: ", value)
                    }else{
                        print("There is error in the server response")
                    }
                case .failure (let error):
                    print("The NTLM request error is: ", error.localizedDescription)
                }

            }
Другие вопросы по тегам