将 Apache HttpComponents 用于具有 NTLM 身份验证的 http 请求 [英] Using Apache HttpComponents for http requests with NTLM authentication

查看:29
本文介绍了将 Apache HttpComponents 用于具有 NTLM 身份验证的 http 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

快速背景.

CFHTTP 不支持 Windows NTLM/Authenticate 身份验证,仅支持基本身份验证.我需要发出必须针对 NTLM 进行身份验证的 http 请求,因此我最终推出了自己的 CFHTTP 版本.

CFHTTP doesn't support Windows NTLM/Authenticate authentication, only basic authentication. I need to make http requests that will have to authenticate against NTLM, so I've ended up rolling my own version of CFHTTP.

我发现 Terry Ryan 的文章使用了apache httpclient 版本 3.1 来执行摘要式身份验证,并使用版本 4.1.2 而不是包含 NTLM 功能.

I found Terry Ryan's article that uses the apache httpclient version 3.1 to perform digest authentication and have built upon that using version 4.1.2 instead which includes NTLM functionality.

我有一个函数将执行一个获取请求,然后其他函数来处理返回一个看起来像 cfhttp 结果集的结构.我所做的更改基于 身份验证教程示例.

I have a function that will perform a get request and then other functions to handle returning a structure that looks like the cfhttp result set. The changes I made are based on the authentication tutorial example.

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;
}

这一直工作正常,直到我更改了执行身份验证的功能.

This was working fine until I altered the function to perform the authentication.

不幸的是我现在得到:

未找到执行方法.

要么没有具有指定方法名称和参数类型的方法,要么执行方法被 ColdFusion 无法可靠解析的参数类型重载.ColdFusion 找到了 2 个与提供的参数匹配的方法.如果这是一个 Java 对象并且您验证了该方法存在,请使用 javacast 函数来减少歧义.

Either there are no methods with the specified method name and argument types or the execute method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 2 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

据我所知,HttpClient 中只有一个匹配的 execute() 函数用于传递给它的对象类,所以我有点困惑.JavaCast 不允许您强制转换为复杂对象或超类型,因此这不起作用.

As far as I can tell there is only one matching execute() function in HttpClient for the object classes passed to it, so I'm a little confused. JavaCast doesn't allow you to cast to complex objects or super types, so that didn't work.

谁能建议我如何让它工作?如何减少歧义?

Can anyone suggest how I can get this to work? How can I reduce the ambiguity?

推荐答案

查看错误,在具有相同数量参数的两个执行方法之间感到困惑.虽然不知道为什么会这样...

Looking at the error, it's getting confused between two execute methods that have the same number of parameters. Although I don't know why it is...

无论如何,我找到了解决错误的方法.它涉及从类中拉出您要使用的方法并直接调用它.如果 ColdFusion 对转换 Java 对象更满意,那么生活可能会更轻松.

Anyway, I found a way around the error. It involves pulling the method you're after out of the class and invoking it directly. If ColdFusion was happier with casting Java objects life might be easier.

//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);

可能有另一种方式来做到这一点(而不是铸造),但这就是我所拥有的;)

There may be another way of doing this (casting instead) but it's all I've got ;)

这篇关于将 Apache HttpComponents 用于具有 NTLM 身份验证的 http 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆