#coldfusion #coldfusion-9 #apache-httpclient-4.x
#coldfusion #coldfusion-9 #apache-httpclient-4.x
Вопрос:
Краткая справка.
CFHTTP не поддерживает аутентификацию Windows NTLM / Authenticate, только базовую аутентификацию. Мне нужно делать http-запросы, которые должны будут проходить аутентификацию в NTLM, поэтому я закончил тем, что запустил свою собственную версию CFHTTP.
Я нашел статью Терри Райана, в которой используется apache httpclient версии 3.1 для выполнения дайджест-аутентификации, и основывался на этом, используя вместо этого версию 4.1.2, которая включает функциональность NTLM.
У меня есть функция, которая будет выполнять запрос get, а затем другие функции для обработки возврата структуры, которая выглядит как набор результатов cfhttp. Внесенные мной изменения основаны на примере учебника по аутентификации.
public any function httpRequest(url,username,password,domain) {
var httpClient = createObject("java","org.apache.http.impl.client.DefaultHttpClient");
var authScope = createObject("java","org.apache.http.auth.AuthScope");
var httpCredentials = createObject("java","org.apache.http.auth.NTCredentials");
var httpGet = createObject("java","org.apache.http.client.methods.HttpGet");
var jURL = createObject("java", "java.net.URL").init(arguments.url);
var host = jURL.getHost();
var path = jURL.getPath();
var httpHostTarget = createObject("java","org.apache.http.HttpHost").init(host,80,"http");
var localContext = createObject("java","org.apache.http.protocol.BasicHttpContext");
var httpContent = {};
var response = '';
if (len(arguments.username) and len(arguments.password) gt 0){
httpCredentials.init(arguments.Username, arguments.password, cgi.remote_host,arguments.domain);
httpClient.getCredentialsProvider().setCredentials(authScope.ANY, httpCredentials);
}
if (!Len(path)) path = "/";
httpGet.init(path);
response = httpClient.execute(httpHostTarget, httpget, localContext);
httpContent = convertHttpClientResponseToCFHTTPFormat(response);
httpClient.getConnectionManager().shutdown();
return httpContent;
}
Это работало нормально, пока я не изменил функцию для выполнения аутентификации.
К сожалению, теперь я получаю :
Метод execute не найден.
Либо нет методов с указанным именем метода и типами аргументов, либо метод execute перегружен типами аргументов, которые ColdFusion не может надежно расшифровать. ColdFusion нашел 2 метода, которые соответствуют предоставленным аргументам. Если это объект Java, и вы подтвердили, что метод существует, используйте функцию javacast для уменьшения неоднозначности.
Насколько я могу судить, в HttpClient есть только одна соответствующая функция execute() для переданных ей классов объектов, поэтому я немного смущен. JavaCast не позволяет выполнять приведение к сложным объектам или супертипам, так что это не сработало.
Может кто-нибудь подсказать, как я могу заставить это работать? Как я могу уменьшить двусмысленность?
Ответ №1:
Глядя на ошибку, она путается между двумя методами выполнения, которые имеют одинаковое количество параметров. Хотя я не знаю, почему это так…
В любом случае, я нашел способ обойти ошибку. Это включает в себя извлечение метода, который вам нужен, из класса и вызов его напрямую. Если бы ColdFusion был более доволен приведением объектов Java, жизнь могла бы быть проще.
//response = httpClient.execute(httpHostTarget, httpget, localContext);
classes = [httpHostTarget.getClass(), CreateObject('java', 'org.apache.http.HttpRequest').getClass(), CreateObject('java', 'org.apache.http.protocol.HttpContext').getClass()];
method = httpClient.getClass().getMethod('execute', classes);
params = [httpHostTarget, httpget, localContext];
response = method.invoke(httpClient, params);
Может быть другой способ сделать это (вместо этого кастинг), но это все, что у меня есть 😉
Комментарии:
1. вполне корректно — это работает, чтобы заставить метод выполняться. Однако, и это проблема, с которой я столкнулся с другими решениями, которые я придумал, код по-прежнему фактически не проходит аутентификацию в IIS и интегрированном входе в систему Windows. Я собираюсь отметить этот вопрос как ответ, потому что это так, но, к сожалению, общая картина по-прежнему нарушается при использовании этих библиотек.
Ответ №2:
Как предположение, вы могли загружать неправильную версию .jars? Похоже, вы не используете JavaLoader, как Райан…
Комментарии:
1. Я как бы обошел всю ошибку JavaLoader, сбросив jar-файлы из http core и client в папку jre / lib / ext на сервере. глядя на методы выполнения объекта httpclient, я могу выбрать тот, который я хочу вызвать, и мои типы объектов для httpHostTarget, httpget и localContext совпадают с ожидаемыми для этого метода и никакими другими, но все же он выдает эту ошибку.
2. @Stephen — В ошибке указано, что найдено два ( 2 ) метода. Я не вижу двух (2) методов, которые соответствуют этой подписи. Если я не пропускаю унаследованный класс .. ?
3. @Leigh Да. Это именно та проблема, с которой я столкнулся. Я вижу только один соответствующий метод. Однако существует 2 метода выполнения с 3 параметрами. Эти методы имеют разные классы для параметров.
4. @Stephen — Не повторять очевидное 😉 .. но что-то кажется подозрительным в том, как CF обнаруживает подписи. Вы знаете, какую версию CF использовал Терри? Потому что я пробовал как его, так и ваш подход (ie
jre/lib/ext
) с CF9, и ни один из них не сработал. Я даже не мог вызвать этот метод с отражением Java, что странно.5. 2009 предложил бы ColdFusion 8 — я на CF 9.0.1. Сегодня мы с коллегой обнаружили, что если вы удаляете локальный контекст, функция выполняется, но мы не можем получить учетные данные для передачи.