HttpClient既支持HTTP标准规范定义的认证模式,又支持一些广泛使用的非标准认证模式,比如NTLM和SPNEGO。
4.1.用户凭证
任何用户认证的过程,都需要一系列的凭证来确定用户的身份。最简单的用户凭证可以是用户名和密码这种形式。UsernamePasswordCredentials
这个类可以用来表示这种情况,这种凭据包含明文的用户名和密码。
这个类对于HTTP标准规范中定义的认证模式来说已经足够了。
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
上述代码会在控制台输出:
user
pwd
NTCredentials
是微软的windows系统使用的一种凭据,包含username、password,还包括一系列其他的属性,比如用户所在的域名。在Microsoft Windows的网络环境中,同一个用户可以属于不同的域,所以他也就有不同的凭据。
NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
上述代码输出:
DOMAIN/user
pwd
4.2. 认证方案
AutoScheme
接口表示一个抽象的面向挑战/响应的认证方案。一个认证方案要支持下面的功能:
- 客户端请求服务器受保护的资源,服务器会发送过来一个chanllenge(挑战),认证方案(Authentication scheme)需要解析、处理这个挑战
- 为processed challenge提供一些属性值:认证方案的类型,和此方案需要的一些参数,这种方案适用的范围
- 使用给定的授权信息生成授权字符串;生成http请求,用来响应服务器发送来过的授权challenge
请注意:一个认证方案可能是有状态的,因为它可能涉及到一系列的挑战/响应。
HttpClient实现了下面几种AutoScheme
:
- Basic: Basic认证方案是在RFC2617号文档中定义的。这种授权方案用明文来传输凭证信息,所以它是不安全的。虽然Basic认证方案本身是不安全的,但是它一旦和TLS/SSL加密技术结合起来使用,就完全足够了。
- Digest: Digest(摘要)认证方案是在RFC2617号文档中定义的。Digest认证方案比Basic方案安全多了,对于那些受不了Basic+TLS/SSL传输开销的系统,digest方案是个不错的选择。
- NTLM: NTLM认证方案是个专有的认证方案,由微软开发,并且针对windows平台做了优化。NTLM被认为比Digest更安全。
- SPNEGO: SPNEGO(Simple and Protected GSSAPI Negotiation Mechanism)是GSSAPI的一个“伪机制”,它用来协商真正的认证机制。SPNEGO最明显的用途是在微软的HTTP协商认证机制拓展上。可协商的子机制包括NTLM、Kerberos。目前,HttpCLient只支持Kerberos机制。(原文:The negotiable sub-mechanisms include NTLM and Kerberos supported by Active Directory. At present HttpClient only supports the Kerberos sub-mechanism.)
4.3. 凭证 provider
凭证providers旨在维护一套用户的凭证,当需要某种特定的凭证时,providers就应该能产生这种凭证。认证的具体内容包括主机名、端口号、realm name和认证方案名。当使用凭据provider的时候,我们可以很模糊的指定主机名、端口号、realm和认证方案,不用写的很精确。因为,凭据provider会根据我们指定的内容,筛选出一个最匹配的方案。
只要我们自定义的凭据provider实现了CredentialsProvider
这个接口,就可以在HttpClient中使用。默认的凭据provider叫做BasicCredentialsProvider
,它使用java.util.HashMap
对CredentialsProvider
进行了简单的实现。
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("somehost", AuthScope.ANY_PORT),
new UsernamePasswordCredentials("u1", "p1"));
credsProvider.setCredentials(
new AuthScope("somehost", 8080),
new UsernamePasswordCredentials("u2", "p2"));
credsProvider.setCredentials(
new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"),
new UsernamePasswordCredentials("u3", "p3"));
System.out.println(credsProvider.getCredentials(
new AuthScope("somehost", 80, "realm", "basic")));
System.out.println(credsProvider.getCredentials(
new AuthScope("somehost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(
new AuthScope("otherhost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(
new AuthScope("otherhost", 8080, null, "ntlm")));
上面代码输出:
[principal: u1]
[principal: u2]
null
[principal: u3]
4.4.HTTP授权和执行上下文
HttpClient依赖AuthState
类去跟踪认证过程中的状态的详细信息。在Http请求过程中,HttpClient创建两个AuthState
实例:一个用于目标服务器认证,一个用于代理服务器认证。如果服务器或者代理服务器需要用户的授权信息,AuthScope
、AutoScheme
和认证信息就会被填充到两个AuthScope
实例中。通过对AutoState
的检测,我们可以确定请求的授权类型,确定是否有匹配的AuthScheme
,确定凭据provider根据指定的授权类型是否成功生成了用户的授权信息。
在Http请求执行过程中,HttpClient会向执行上下文中添加下面的授权对象:
-
Lookup
对象,表示使用的认证方案。这个对象的值可以在本地上下文中进行设置,来覆盖默认值。 -
CredentialsProvider
对象,表示认证方案provider,这个对象的值可以在本地上下文中进行设置,来覆盖默认值。 -
AuthState
对象,表示目标服务器的认证状态,这个对象的值可以在本地上下文中进行设置,来覆盖默认值。 -
AuthState
对象,表示代理服务器的认证状态,这个对象的值可以在本地上下文中进行设置,来覆盖默认值。 -
AuthCache
对象,表示认证数据的缓存,这个对象的值可以在本地上下文中进行设置,来覆盖默认值。
我们可以在请求执行前,自定义本地HttpContext
对象来设置需要的http认证上下文;也可以在请求执行后,再检测HttpContext
的状态,来查看授权是否成功。
CloseableHttpClient httpclient = <...>
CredentialsProvider credsProvider = <...>
Lookup<AuthSchemeProvider> authRegistry = <...>
AuthCache authCache = <...>
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthSchemeRegistry(authRegistry);
context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("http://www.yeetrack.com/");
CloseableHttpResponse response1 = httpclient.execute(httpget, context);
<...>
AuthState proxyAuthState = context.getProxyAuthState();
System.out.println("Proxy auth state: " + proxyAuthState.getState());
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
AuthState targetAuthState = context.getTargetAuthState();
System.out.println("Target auth state: " + targetAuthState.getState());
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
4.5. 缓存认证数据
从版本4.1开始,HttpClient就会自动缓存验证通过的认证信息。但是为了使用这个缓存的认证信息,我们必须在同一个上下文中执行逻辑相关的请求。一旦超出该上下文的作用范围,缓存的认证信息就会失效。
4.6. 抢先认证
HttpClient默认不支持抢先认证,因为一旦抢先认证被误用或者错用,会导致一系列的安全问题,比如会把用户的认证信息以明文的方式发送给未授权的第三方服务器。因此,需要用户自己根据自己应用的具体环境来评估抢先认证带来的好处和带来的风险。
即使如此,HttpClient还是允许我们通过配置来启用抢先认证,方法是提前填充认证信息缓存到上下文中,这样,以这个上下文执行的方法,就会使用抢先认证。
CloseableHttpClient httpclient = <...>
HttpHost targetHost = new HttpHost("localhost", 80, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("username", "password"));
// 创建 AuthCache 对象
AuthCache authCache = new BasicAuthCache();
//创建 BasicScheme,并把它添加到 auth cache中
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// 把AutoCache添加到上下文中
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
HttpGet httpget = new HttpGet("/");
for (int i = 0; i < 3; i++) {
CloseableHttpResponse response = httpclient.execute(
targetHost, httpget, context);
try {
HttpEntity entity = response.getEntity();
} finally {
response.close();
}
}
4.7. NTLM认证
从版本4.1开始,HttpClient就全面支持NTLMv1、NTLMv2和NTLM2认证。当人我们可以仍旧使用外部的NTLM引擎(比如Samba开发的JCIFS库)作为与Windows互操作性程序的一部分。
4.7.1. NTLM连接持久性
相比Basic
和Digest
认证,NTLM认证要明显需要更多的计算开销,性能影响也比较大。这也可能是微软把NTLM协议设计成有状态连接的主要原因之一。也就是说,NTLM连接一旦建立,用户的身份就会在其整个生命周期和它相关联。NTLM连接的状态性使得连接持久性更加复杂,The stateful nature of NTLM connections makes connection persistence more complex, as for the obvious reason persistent NTLM connections may not be re-used by users with a different user identity. HttpClient中标准的连接管理器就可以管理有状态的连接。但是,同一会话中逻辑相关的请求,必须使用相同的执行上下文,这样才能使用用户的身份信息。否则,HttpClient就会结束旧的连接,为了获取被NTLM协议保护的资源,而为每个HTTP请求,创建一个新的Http连接。更新关于Http状态连接的信息,点击此处。
由于NTLM连接是有状态的,一般推荐使用比较轻量级的方法来处罚NTLM认证(如GET、Head方法),然后使用这个已经建立的连接在执行相对重量级的方法,尤其是需要附件请求实体的请求(如POST、PUT请求)。
CloseableHttpClient httpclient = <...>
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new NTCredentials("user", "pwd", "myworkstation", "microsoft.com"));
HttpHost target = new HttpHost("www.microsoft.com", 80, "http");
//使用相同的上下文来执行逻辑相关的请求
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
//使用轻量级的请求来触发NTLM认证
HttpGet httpget = new HttpGet("/ntlm-protected/info");
CloseableHttpResponse response1 = httpclient.execute(target, httpget, context);
try {
HttpEntity entity1 = response1.getEntity();
} finally {
response1.close();
}
//使用相同的上下文,执行重量级的方法
HttpPost httppost = new HttpPost("/ntlm-protected/form");
httppost.setEntity(new StringEntity("lots and lots of data"));
CloseableHttpResponse response2 = httpclient.execute(target, httppost, context);
try {
HttpEntity entity2 = response2.getEntity();
} finally {
response2.close();
}
4.8. SPNEGO/Kerberos认证
SPNEGO(Simple and Protected GSSAPI Megotiation Mechanism),当双方均不知道对方能使用/提供什么协议的情况下,可以使用SP认证协议。这种协议在Kerberos认证方案中经常使用。It can wrap other mechanisms, however the current version in HttpClient is designed solely with Kerberos in mind.
4.8.1. 在HTTPCIENT中使用SPNEGO
SPNEGO认证方案兼容Sun java 1.5及以上版本。但是强烈推荐jdk1.6以上。Sun的JRE提供的类就已经几乎完全可以处理Kerberos和SPNEGO token。这就意味着,需要设置很多的GSS类。SpnegoScheme
是个很简单的类,可以用它来handle marshalling the tokens and 读写正确的头消息。
最好的开始方法就是从示例程序中找到KerberosHttpClient.java
这个文件,尝试让它运行起来。运行过程有可能会出现很多问题,但是如果人品比较高可能会顺利一点。这个文件会提供一些输出,来帮我们调试。
在Windows系统中,应该默认使用用户的登陆凭据;当然我们也可以使用kinit
来覆盖这个凭据,比如$JAVA_HOME\bin\kinit testuser@AD.EXAMPLE.NET
,这在我们测试和调试的时候就显得很有用了。如果想用回Windows默认的登陆凭据,删除kinit创建的缓存文件即可。
确保在krb5.conf文件中列出domain_realms
。这能解决很多不必要的问题。
4.8.2. 使用GSS/JAVA KERBEROS
下面的这份文档是针对Windows系统的,但是很多信息同样适合Unix。
org.ietf.jgss
这个类有很多的配置参数,这些参数大部分都在krb5.conf/krb5.ini
文件中配置。更多的信息,参考此处。
login.conf文件
下面是一个基本的login.conf文件,使用于Windows平台的IIS和JBoss Negotiation模块。
系统配置文件java.security.auth.login.config
可以指定login.conf
文件的路径。login.conf
的内容可能会是下面的样子:
com.sun.security.jgss.login {
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};
com.sun.security.jgss.accept {
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};
4.8.4. KRB5.CONF / KRB5.INI 文件
如果没有手动指定,系统会使用默认配置。如果要手动指定,可以在java.security.krb5.conf
中设置系统变量,指定krb5.conf
的路径。krb5.conf
的内容可能是下面的样子:
[libdefaults]
default_realm = AD.EXAMPLE.NET
udp_preference_limit = 1
[realms]
AD.EXAMPLE.NET = {
kdc = KDC.AD.EXAMPLE.NET
}
[domain_realms]
.ad.example.net=AD.EXAMPLE.NET
ad.example.net=AD.EXAMPLE.NET
4.8.5. WINDOWS详细的配置
为了允许Windows使用当前用户的tickets,javax.security.auth.useSubjectCredsOnly
这个系统变量应该设置成false
,并且需要在Windows注册表中添加allowtgtsessionkey
这个项,而且要allow session keys to be sent in the Kerberos Ticket-Granting Ticket.
Windows Server 2003和Windows 2000 SP4,配置如下:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
Windows XP SP2 配置如下:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
本文链接地址: HttpClient4.3教程 第四章 HTTP认证
相关推荐
4. **实体编码(Entity Encodings)**:HttpClient 4.3处理各种HTTP实体编码,如Chunked Transfer Coding和Content-Encoding。这使得发送大文件或接收流式响应成为可能。 5. **请求和响应的配置**:你可以为每个...
这个教程可能是针对开发者设计的,帮助他们深入理解和有效地使用HttpClient 4.3进行网络请求。 HttpClient 4.3的关键知识点包括: 1. **基本概念**:HttpClient主要处理HTTP请求和响应,包括GET、POST、PUT、...
HttpClient 4.3封装工具类支持配置HTTP代理或SOCKS代理,包括设置代理的主机名、端口号,以及代理认证等。这样,即使在需要代理的网络环境中,也能正常发起HTTP请求。 2. **多线程问题**:在处理大量并发请求时,...
4. **Apache HttpComponents Client**:HttpClient的其他相关组件,如Cookie管理、认证和重定向处理。 5. **Java Cryptography Extension (JCE)**:用于SSL/TLS加密操作,可能需要根据系统需求安装。 6. **Java ...
《HttpClient 4.3与HttpCore 4.4详解》 在Java开发中,HttpClient库是进行HTTP通信的重要工具,而HttpCore则是HttpClient的核心组件,它们共同为开发者提供了强大且灵活的HTTP客户端服务。本文将深入探讨HttpClient...
在这个"httpClient4.3 Jar包 demo"中,你将找到HttpClient 4.3的jar文件以及相关的示例代码,对于学习和理解HttpClient的使用非常有帮助。 HttpClient 4.3主要知识点包括: 1. **基础概念**: - **HttpClient对象...
4. **Cookie管理**:HttpClient 4.3支持标准的Cookie管理,包括`BasicCookieStore`和`CookieSpecRegistry`,可以方便地处理服务器返回的Cookie信息。 5. **认证机制**:HttpClient提供了多种认证策略,如`...
HttpClient 4.3 是 Apache 开源组织提供的一款用于执行 HTTP 请求的 Java 库。这个库在 Java 开发中被广泛使用,特别是在需要与 Web 服务器交互或者进行 API 调用时。HttpClient 4.3 版本是该库的一个稳定版本,提供...
HttpClient 4.3是一个重要的版本,它提供了许多改进和新特性,使得开发者可以更高效、更灵活地与Web服务器进行交互。这个压缩包包含了HttpClient 4.3版本所需的jar文件和其他依赖库,以确保能够正确运行基于...
本教程将详细介绍HttpClient 4.3的主要特性和使用方法。 一、HttpClient简介 HttpClient是一个Java库,它允许开发人员执行HTTP和HTTPS请求,并处理响应。它支持各种HTTP方法(如GET、POST、PUT、DELETE等),提供了...
### HttpClient 4.3 中文版相关知识点 #### 一、概述 Apache HttpClient 是一个用于构建 HTTP 客户端的应用程序编程接口 (API),属于 Apache Jakarta Commons 的一部分。该库支持 HTTP 协议的最新标准,并提供了...
1. HTTP协议支持:HttpClient 4.3全面支持HTTP/1.1和部分HTTP/2规范,包括GET、POST、PUT、DELETE等多种HTTP方法,以及Cookie管理、重定向处理、连接管理和认证等机制。 2. 连接管理:HttpClient 4.3引入了更高效的...
标题 "HTTPClient 4.3.X" 涉及的是Apache HttpClient库的一个版本,这是一个广泛使用的Java库,用于实现客户端HTTP通信。这个库为开发者提供了丰富的功能,包括发送HTTP请求,处理响应,管理连接池,处理cookies,...
HttpClient 4.3教程 HttpClient是Apache基金会下的一个开源项目,提供了一个功能强大且灵活的HTTP客户端库。HttpClient致力于填补Java中的空白,提供了一个功能丰富的HTTP客户端库,可以实现HTTP客户端的各种需求。...
HttpClient 4.3 是 Apache 开源组织提供的一个用于构建 HTTP 客户端应用程序的强大库,主要专注于 HTTP 协议的实现。它建立在 HttpCore 库之上,支持传统的阻塞 I/O 模型,适用于各种需要高效、可控的 HTTP 交互的...
HTTPClient是Java编程中用于处理HTTP协议的库,版本4.3是一个常用且稳定的版本。在进行网络爬虫开发时,HTTPClient库扮演了至关重要的角色,它提供了丰富的功能,如发起HTTP请求、处理响应、管理Cookie、实现重试...
### HttpClient4.3教程知识点详解 #### 一、引言 在互联网技术中,HTTP协议作为数据通信的基础标准之一,其重要性不言而喻。随着互联网应用的不断发展与变化,HTTP协议也在不断地进化和扩展,以适应更多场景的需求...
于是,便诞生了Apache HttpClient这样的第三方库,其主要目的是为了提供更为丰富和高效的HTTP客户端功能。 Apache HttpClient是一个开源的Java HTTP客户端库,主要用于执行HTTP方法,如GET、POST、PUT、DELETE等。...
HttpClient 4.3是其一个重要的版本,提供了许多新特性和改进,以提升性能和易用性。这个压缩包包含两份文档,一份是.docx格式,一份是.pdf格式,两者内容相同,都是关于HttpClient 4.3的中文版指南。 HttpClient的...
javase http通讯技术 apache httpclient4.3 设置代理详解