GVKun编程网logo

使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常

9

本篇文章给大家谈谈使用NTLM进行身份验证时,HttpClient4.1.1返回401,浏览器工作正常,同时本文还将给你拓展.NET中如何选择WebClient,HttpClient,HttpWebR

本篇文章给大家谈谈使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常,同时本文还将给你拓展.NET 中如何选择 WebClient,HttpClient,HttpWebRequest、Android httpclient – 获取具有抢先身份验证的文件、Android中的HttpClient身份验证、Apache HttpClient 4.1-代理身份验证等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常

使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常

我正在尝试使用Apache / Jakarta HttpClient
4.1.1使用给定的凭据连接到任意网页。为了测试这一点,我在运行只有一次身份验证模式的开发机上安装了IIS
7.5的最小安装。基本身份验证工作正常,但是每当我尝试登录时,摘要和NTLM都会返回401错误消息。这是我的代码:

    DefaultHttpClient httpclient = new DefaultHttpClient();    HttpContext localContext = new BasicHttpContext();    HttpGet httpget = new HttpGet("http://localhost/");     CredentialsProvider credsProvider = new BasicCredentialsProvider();    credsProvider.setCredentials(AuthScope.ANY,            new NTCredentials("user", "password", "", "localhost"));    if (!new File(System.getenv("windir") + "\\krb5.ini").exists()) {        List<String> authtypes = new ArrayList<String>();        authtypes.add(AuthPolicy.NTLM);        authtypes.add(AuthPolicy.DIGEST);        authtypes.add(AuthPolicy.BASIC);        httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF,                authtypes);        httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF,                authtypes);    }    localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);    HttpResponse response = httpclient.execute(httpget, localContext);    System.out.println("Response code: " + response.getStatusLine());

我在Fiddler中注意到的一件事是Firefox与HttpClient发送的哈希值不同,这使我认为IIS
7.5可能期望比HttpClient提供的哈希更好?有任何想法吗?如果我可以验证它是否适用于NTLM,那就太好了。摘要也很好,但是如果有必要,我可以不用它。

答案1

小编典典

我不是该主题的专家,但是在使用http组件进行NTLM身份验证期间,我发现客户端需要进行3次尝试才能连接到NTML端点。这里对Spnego进行了描述,但对于NTLM身份验证则有所不同。

对于第一次尝试使用NTLM的客户端,客户端将发出请求,Target auth state: UNCHALLENGED并且Web服务器将返回HTTP
401状态和标头:WWW-Authenticate: NTLM

客户端将检查配置的身份验证方案,应在客户端代码中配置NTLM。

第二次尝试,客户端将使用发送请求Target auth state:CHALLENGED,并发送带有以base64格式编码的令牌的授权标头:Authorization: NTLMTlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw== 服务器再次返回HTTP
401状态,但标头:WWW-Authenticate: NTLM现在已填充编码信息。

3rd Attempt客户端将使用WWW-Authenticate: NTLM 标头中的信息,并通过Target auth state:HANDSHAKEAuthorization: NTLM包含服务器更多信息的授权标头进行最终请求。

就我而言,HTTP/1.1 200 OK之后我会收到。

为了避免所有请求文档中的所有问题,第4.7.1章指出,对于逻辑相关的请求,必须使用相同的执行令牌。对我来说,它没有用。

我的代码:我@PostConstruct使用EJB方法初始化一次客户端

        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();        cm.setMaxTotal(18);        cm.setDefaultMaxPerRoute(6);        RequestConfig requestConfig = RequestConfig.custom()        .setSocketTimeout(30000)        .setConnectTimeout(30000)        .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM))        .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))        .build();        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();        credentialsProvider.setCredentials(AuthScope.ANY,                new NTCredentials(userName, password, hostName, domainName));        // Finally we instantiate the client. Client is a thread safe object and can be used by several threads at the same time.         // Client can be used for several request. The life span of the client must be equal to the life span of this EJB.         this.httpclient = HttpClients.custom()        .setConnectionManager(cm)        .setDefaultCredentialsProvider(credentialsProvider)        .setDefaultRequestConfig(requestConfig)        .build();

在每个请求中使用相同的客户端实例:

            HttpPost httppost = new HttpPost(endPoint.trim());                        // HttpClientContext is not thread safe, one per request must be created.            HttpClientContext context = HttpClientContext.create();                response = this.httpclient.execute(httppost, context);

在我的EJB的@PreDestroy方法中,释放资源并将连接返回到连接管理器:

             this.httpclient.close();

.NET 中如何选择 WebClient,HttpClient,HttpWebRequest

.NET 中如何选择 WebClient,HttpClient,HttpWebRequest

当我们在用 .NET 调用 RestAPI 时通常有三种选择,分别为:WebClient,HttpWebRequest,HttpClient,这篇文章我们将会讨论如何使用这三种方式去调用 RestAPI,我还会提供相应的代码案例来帮助你更好的理解这三者的概念和使用方式,简单来说:

  • HttpWebRequest 是一种相对底层的处理 Http request/response 的方式。

  • WebClient 提供了对 HttpWebRequest 的高层封装,来简化使用者的调用。

  • HttpClient 是一种新的处理 Http request/response 工具包,具有更高的性能。

接下来我们讨论一下抽象类 WebRequest

WebRequest

WebRequest 是一种基于特定的 http 实现,它是一个抽象类,所以在处理 Reqeust 请求时底层会根据传进来的 url 生成相应的子类,如:HttpWebRequest 或 FileWebRequest ,下面的代码展示了如何使用 WebRequest。


WebRequest webRequest = WebRequest.Create(uri);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Method ="GET";
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

WebRequest 是 .NET Framework 中第一个用来处理 Http 请求的类,在处理 Http请求和响应 方面给调用者提供了诸多的灵活性,你还可以使用这个类来存取 headers,cookies,protocols 和 timeouts 等等,下面的代码展示了其实现子类 HttpWebRequest 是如何使用的。


HttpWebRequest http = HttpWebRequest)WebRequest.Create(“http://localhost:8900/api/default”);
WebResponse response = http.GetResponse();
MemoryStream memoryStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(memoryStream);
string data = streamReader.ReadToEnd();

WebClient

WebClient 是 HttpWebRequest 的高层封装,它给调用者提供了更便捷的使用方式,理所当然做出的牺牲就是 WebClient 的性能略逊于 HttpWebRequest,如果你的业务场景只是简单访问第三方的 Http Service,那么我建议你使用 WebClient ,同理如果你有更多的精细化配置则使用 HttpWebRequest,下面的代码展示了如何使用 WebClient 。


string data = null;

using (var webClient = new WebClient())
{
    data = webClient.DownloadString(url);
}

HttpClient

HttpClient 是在 .NET Framework 4.5 中被引入的,如果你的项目是基于 .NET 4.5 以上版本,除一些特定的原因之外,建议你优先使用 HttpClient,本质上来说,HttpClient 作为后来之物,它吸取了 HttpWebRequest 的灵活性及 WebClient 的便捷性,所以说

Android httpclient – 获取具有抢先身份验证的文件

Android httpclient – 获取具有抢先身份验证的文件

我使用此示例代码获取网站的 HTML代码时遇到问题.

http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java

我必须使用上面的那个,因为我需要在我的Android应用程序中进行抢先身份验证.

我认为解决方案可能是httpget对象,但我仍然只得到错误:(
C.F. HttpGet httpget = new HttpGet(“/ index.html”);

有没有人知道如何获取文件的内容,使用链接的示例代码在上面的httpget对象中指定.它肯定叫,但现在我只能得到状态代码等等……

谢谢4帮助

解决方法

当我去年解决这个问题时,我放弃了HttpClient的原生抢先式HTTP身份验证,而且只放弃了 rolled the header myself.

Android中的HttpClient身份验证

Android中的HttpClient身份验证

我试图从需要完全身份验证的android访问Web服务.我为此使用基本的HTTP身份验证.

我试过设置UserNamePasswordCredentials以及在HttpGet请求中设置标头,但都可以.请告诉我我在做什么错.

我用于在HttpGet请求中设置标头的代码:

HttpGet requestLogin = new HttpGet(url);               
requestLogin.addHeader("Authorization", "Basic " + Base64.encodetoString((username+":"+password).getBytes(), Base64.NO_WRAP));

我用来设置UserNamePassword凭据的代码:

DefaultHttpClient httpClient = new DefaultHttpClient(mgr, tempClient.getParams());
httpClient.getCredentialsProvider().setCredentials(
                   AuthScope.ANY,
                    new UsernamePasswordCredentials(username,password));

这是我在使用此代码时遇到的异常:

05-26 17:21:22.234: E/res(1651): <html><head><title>Apache Tomcat/6.0.35 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Bad credentials</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Bad credentials</u></p><p><b>description</b> <u>This request requires HTTP authentication (Bad credentials).</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/6.0.35</h3></body></html>

当我在浏览器上使用这些相同的凭据时,它可以工作.因此,凭据不是不正确的.请让我知道我在做什么错.我完全陷入其中.

提前致谢.

解决方法:

我刚刚尝试了手动的HTTP标头变体,它应该与Base64.Default标志一起使用:

requestLogin.addHeader("Authorization", "Basic " +
    Base64.encodetoString((username+":"+password).getBytes(), Base64.DEFAULT));

Apache HttpClient 4.1-代理身份验证

Apache HttpClient 4.1-代理身份验证

我一直在尝试使用Apaches
HttpComponent的httpclient时从配置的属性中配置用于代理身份验证的用户和密码,但是没有成功。我发现的所有示例都引用了不再可用的方法和类,例如HttpStatesetProxyCredentials

因此,谁能给我一个有关如何配置代理凭据的示例?

答案1

小编典典

对于Basic-Auth,它看起来像这样:

DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.getCredentialsProvider().setCredentials(    new AuthScope("PROXY HOST", 8080),    new UsernamePasswordCredentials("username", "password"));HttpHost targetHost = new HttpHost("TARGET HOST", 443, "https");HttpHost proxy = new HttpHost("PROXY HOST", 8080);httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

开箱即用不支持AFAIK
NTLM。但是您也许可以使用NTCredentials过载来管理它DefaultProxyAuthenticationHandler

关于使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于.NET 中如何选择 WebClient,HttpClient,HttpWebRequest、Android httpclient – 获取具有抢先身份验证的文件、Android中的HttpClient身份验证、Apache HttpClient 4.1-代理身份验证等相关内容,可以在本站寻找。

本文标签: