HTTPCLIENT的授权方式简介

Server Authentication

HttpClient handles authenticating with servers almost transparently, the only thing a developer must do is actually provide the login credentials. These credentials are stored in the HttpState instance and can be set or retrieved using the setCredentials(AuthScope authscope, Credentials cred) and getCredentials(AuthScope authscope) methods.

The automatic authorization built in to HttpClient can be disabled with the method setDoAuthentication(boolean doAuthentication) in the HttpMethod class. The change only affects that method instance.

Preemptive Authentication

Preemptive authentication can be enabled within HttpClient. In this mode HttpClient will send the basic authentication response even before the server gives an unauthorized response in certain situations, thus reducing the overhead of making the connection. To enable this use the following:

client.getParams().setAuthenticationPreemptive(true);

Preemptive authentication mode also requires default Credentials to be set for the target or proxy host against which preemptive authentication is to be attempted. Failure to provide default credentials will render the preemptive authentication mode ineffective.

Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(new AuthScope("myhost", 80, AuthScope.ANY_REALM), defaultcreds);

The preemptive authentication in HttpClient conforms to 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.

Security aspects of server authentication

Use default credentials with caution when developing applications that may need to communicate with untrusted web sites or web applications. When preemptive authentication is activated or credentials are not explicitly given for a specific authentication realm and host HttpClient will use default credentials to try to authenticate with the target site. If you want to avoid sending sensitive credentials to an untrusted site, narrow the credentials scope as much as possible: always specify the host and, when known, the realm the credentials are intended for.

Setting credentials with AuthScope.ANY authentication scope (null value for host and/or realm) is highly discouraged in production applications. Doing this will result in the credentials being sent for all authentication attempts (all requests in the case of preemptive authentication). Use of this setting should be limited to debugging only.

// To be avoided unless in debug mode
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(AuthScope.ANY, defaultcreds);

Proxy Authentication

Proxy authentication in HttpClient is almost identical to server authentication with the exception that the credentials for each are stored independantly. So for proxy authentication you must use setProxyCredentials(AuthScope authscope, Credentials cred) and getProxyCredentials(AuthScope authscope).

Authentication Schemes

The following authentication schemes are supported by HttpClient.

Basic

Basic authentication is the original and most compatible authentication scheme for HTTP. Unfortunately, it is also the least secure as it sends the username and password unencrypted to the server. Basic authentication requires an instance of UsernamePasswordCredentials (which NTCredentials extends) to be available, either for the specific realm specified by the server or as the default credentials.

Digest

Digest authentication was added in the HTTP 1.1 protocol and while not being as widely supported as Basic authentication there is a great deal of support for it. Digest authentication is significantly more secure than basic authentication as it never transfers the actual password across the network, but instead uses it to encrypt a "nonce" value sent from the server.

Digest authentication requires an instance of UsernamePasswordCredentials (which NTCredentials extends) to be available either for the specific realm specified by the server or as the default credentials.

NTLM

NTLM is the most complex of the authentication protocols supported by HttpClient. It is a proprietary protocol designed by Microsoft with no publicly available specification. Early version of NTLM were less secure than Digest authentication due to faults in the design, however these were fixed in a service pack for Windows NT 4 and the protocol is now considered more secure than Digest authentication.

NTLM authentication requires an instance of NTCredentials be available for the domain name of the server or the default credentials. Note that since NTLM does not use the notion of realms HttpClient uses the domain name of the server as the name of the realm. Also note that the username provided to the NTCredentials should not be prefixed with the domain - ie: "adrian" is correct whereas "DOMAIN/adrian" is not correct.

There are some significant differences in the way that NTLM works compared with basic and digest authentication. These differences are generally handled by HttpClient, however having an understanding of these differences can help avoid problems when using NTLM authentication.

 

  1. NTLM authentication works almost exactly the same as any other form of authentication in terms of the HttpClient API. The only difference is that you need to supply 'NTCredentials' instead of 'UsernamePasswordCredentials' (NTCredentials actually extends UsernamePasswordCredentials so you can use NTCredentials right throughout your application if need be).
  2. The realm for NTLM authentication is the domain name of the computer being connected to, this can be troublesome as servers often have multiple domain names that refer to them. Only the domain name that HttpClient connects to (as specified by the HostConfiguration) is used to look up the credentials. It is generally advised that while initially testing NTLM authentication, you pass the realm in as null which is used as the default.
  3. NTLM authenticates a connection and not a request, so you need to authenticate every time a new connection is made and keeping the connection open during authentication is vital. Due to this, NTLM cannot be used to authenticate with both a proxy and the server, nor can NTLM be used with HTTP 1.0 connections or servers that do not support HTTP keep-alives.

 

For a detailed explanation of how NTLM authentication works, please see

http://davenport.sourceforge.net/ntlm.html .

Troubleshooting

Some authentication schemes may use cryptographic algorithms. It is recommended to include the

String secProviderName = "com.sun.crypto.provider.SunJCE");
java.security.Provider secProvider = 
    (java.security.Provider)Class.forName(secProviderName).newInstance();
Security.addProvider(secProvider);
Java Cryptography Extension in your runtime environment prior to JDK 1.4. Also note that you must register the JCE implementation manually as HttpClient will not do so automatically. For instance to register the Sun JCE implementation, you should execute the following code before attempting to use HttpClient.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值