1.服务器认证(Server Authentication)HttpClient处理服务器认证几乎是透明的,仅须要开发人员提供登陆信息(login credentials)。登陆信息保存在HttpState类的实例中,能够经过 setCredentials(String realm, Credentials cred)和getCredentials(String realm)来获取或设置。HttpClient内建的自动认证,能够经过HttpMethod类的setDoAuthentication(boolean doAuthentication)方法关闭,并且此次关闭只影响HttpMethod当前的实例。html
1.1抢先认证(Preemptive Authentication)在这种模式时,HttpClient会主动将basic认证应答信息传给服务器,即便在某种状况下服务器可能返回认证失败的应答,这样作主要是为了减小链接的创建。使用该机制以下所示:
client.getParams().setAuthenticationPreemptive(true);
抢先认证模式也提供对于特定目标或代理的缺省认证。若是没有提供缺省的认证信息,则该模式会失效。
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");client.getState().setCredentials(new AuthScope("myhost", 80, AuthScope.ANY_REALM), defaultcreds);
Httpclient实现的抢先认证遵循rfc2617.
A client SHOULD assume that all paths at or deeper than the depth of the last symbolic element in the path field of the Request-URI also are within the protection space specified by the Basic realm value of the current challenge. A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server. Similarly, when a client sends a request to a proxy, it may reuse a userid and password in the Proxy-Authorization header field without receiving another challenge from the proxy server.
1.2服务器认证的安全方面考虑当须要与不被信任的站点或web应用通讯时,应该谨慎使用缺省的认证机制。当启动(activate)抢先认证模式,或者认证中没有明确给出认证域,主机的HttpClient将使用缺省的认证机制去试图得到目标站点的受权。若是你提供的认证信息是敏感的,你应该指定认证域。不推荐将认证域指定为AuthScope.ANY。(只有在debugging状况下,才使用)
// To be avoided unless in debug modeCredentials defaultcreds = new UsernamePasswordCredentials("username", "password");client.getState().setCredentials(AuthScope.ANY, defaultcreds); web
2.代理认证(proxy authentication) 除了登陆信息需单独存放之外,代理认证与服务器认证几乎一致。用 setProxyCredentials(String realm, Credentials cred)和 getProxyCredentials(String realm)设、取登陆信息。安全
3.认证方案(authentication schemes)服务器
3.1 Basic是HTTP中规定最先的也是最兼容的方案,遗憾的是也是最不安全的一个方案,由于它以明码传送用户名和密码。它要求一个UsernamePasswordCredentials实例,能够指定服务器端的访问空间或采用默认的登陆信息。 网络
3.2 Digest是在HTTP1.1 中增长的一个方案,虽然不如Basic获得的软件支持多,但仍是有普遍的使用。less
Digest方案比Basic方案安全得多,因它根本就不经过网络传送实际的密码,传送的是利用这个密码对从服务器传来的一个随机数(nonce)的加密串。它要求一个UsernamePasswordCredentials实例,能够指定服务器端的访问空间或采用默认的登陆信息。 ide
3.3 NTLM这是HttpClient支持的最复杂的认证协议。它Microsoft设计的一个私有协议,没有公开的规范说明。一开始因为设计的缺陷,NTLM的安全性比 Digest差,后来通过一个ServicePack补丁后,安全性则比较Digest高。NTLM须要一个NTCredentials实例。 注意,因为NTLM不使用访问空间(realms)的概念,HttpClient利用服务器的域名做访问空间的名字。还须要注意,提供给NTCredentials的用户名,不要用域名的前缀 - 如: "adrian" 是正确的,而 "DOMAIN\adrian" 则是错的。NTLM认证的工做机制与basic和digest有很大的差异。这些差异通常由HttpClient处理,但理解这些差异有助避免在使用NTLM认证时出现错误。[1] 从HttpClientAPI的角度来看,NTLM与其它认证方式同样的工做,差异是须要提供'NTCredentials'实例而不是'UsernamePasswordCredentials'(其实,前者只是扩展了后者)[2] 对NTLM认证,访问空间是链接到的机器的域名,这对多域名主机会有一些麻烦。只有HttpClient链接中指定的域名才是认证用的域名。建议将realm设为null以使用默认的设置。[3] NTLM只是认证了一个链接而不是一请求,因此每当一个新的链接创建就要进行一次认证,且在认证的过程当中保持链接是很是重要的。 所以,NTLM不能同时用于代理认证和服务器认证,也不能用于HTTP1.0链接或服务器不支持持久链接(keep-alives)的状况。关于NTLM认证机制更详细的研究,可参考http://davenport.sourceforge.net/ntlm.html 。 加密
3.4选择认证一些服务器支持多种认证方案。假设一次只能使用一种认证方案,HttpClient必须选择使用哪一种。spa
HttpClient选择是基于NTLM, Digest, Basic顺序的。在具体状况下,能够更改该顺序。.net
可经过参数'http.auth.scheme-priority'来实现,该参数值应该被存放在一个String类型的List中。选择优先级是按插入顺序肯定的。
HttpClient client = new HttpClient();
List authPrefs = new ArrayList(2);
authPrefs.add(AuthPolicy.DIGEST);
authPrefs.add(AuthPolicy.BASIC);// This will exclude the NTLM
authentication schemeclient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
3.5定制认证方案HttpClient自己支持basic, digest, and NTLM这三种认证方案。同时,它也提供了加载额外定制的认证方案的功能(经过AuthScheme接口实现)。
须要使用定制的认证方案,必须实现下面的步骤:
[1]实现AuthScheme接口。
[2]经过AuthPolicy.registerAuthScheme() 注册定制的AuthScheme。
[3]将定制的AuthScheme加入到AuthPolicy.AUTH_SCHEME_PRIORITY中。