Java CookBook Learning Day4th--HTTP (by Tim O'Brien)

 1.9. Basic Authentication

 1.9.1. Problem

  You need to access information protected by HTTP Basic Authentication.

  1.9.2.Solution

  Create a UsernamePasswordCredentials object with a username and password. Add this Credentials object to the instance of HttpState associated with an HttpClient object. HttpClient will attempt to execute a message, and the server will response with 401 response code;HttpClient will then retry the request with the appropriate Authorization header. The following example uses a UsernamePasswordCredentials object to access a protected resource:

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.Exception;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.GetMethod;
HttpClient client = new HttpClient( );
HttpState state = client.getState( );
//Set credentials on the client
Credentials credentials = new UsernamePasswordCredentials("testuser","crazypass");
state.setCredentials( null, null, credentials);
String url = "http://www.discursive.com/jccook/auth/";
HttpMethod method = new GetMethod( url );
client.executeMethod( method);
String response = method.getReponseBodyAsString( );
method.releaseConnection( );

  This example executes a GetMethod, the server requests credentials, and the credentials are sent to the server. The final
response is:

<html>
<head>
<title>Secure JCCook Example</title>
</head>
<body>
<h1>Hello Secure World!</h1>
</body>
</html>

  1.9.3.Discussion

  The previous example added a UsernamePasswordCredentials object to the HttpState with a null authentication realm and null host; this makes the supplied UsernamePasswordCredentials object the default instance to use for all authentication realms and hosts. The requests and response created by this example demonstrate the inner-workings of HttpClient, which sent the following request when the GetMethod was executed:

GET /jccook/auth/ HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: www.discursive.com

 The server then responds with a 401 response code, telling the client that authorization is required. The WWW-Authenticate header specifies that the server is expecting Basic authentication, and the authentication realm is jccook realm:

HTTP/1.1 401 Authorization Required  
Date: Fri, 14 May 2004 20:40:59 GMT
Server: Apache/2.0.48 (Fedora)
WWW-Authenticate: Basic realm="jccook realm"
Content-Length: 487
Content-Type: text/html; charset=iso-8859-1
DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
title>401 Authorization Required</title>
</head><body>
.... error message

  The server did not return the information needed, and another request needs to be made, sending the credentials in an Authorization request header. Since the initial request was made with HTTP/1.1, the connection is not closed after the response, and a second request will be sent over the same connection. This second request is the same as the first request except for an Authorization header. HttpClient looked at the associated HttpState object and located the appropriate Credentials object to use to create the Authorization header:

GET /jccook/auth/ HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: www.discursive.com
Authorization: Basic dGVzdHVzZXI6Y3JhenlwYXNz

 Finally, the server replies with a 200 response code and the content of the requested resource:

HTTP/1.1 200 OK
Date: Fri, 14 May 2004 20:40:59 GMT
Server: Apache/2.0.48 (Fedora)
Last-Modified: Wed, 05 May 2004 02:51:59 GMT
ETag: "a06d2-76-829811c0"
Accept-Ranges: bytes
Content-Length: 118
Content-Type: text/html; charset=UTF-8
<html>
<head>
<title>Secure JCCook Example</title>
</head>
<body>
<h1>Hello Secure World!</h1>
</body>
</html>

  HttpClient waits for the server to send back a 401 response code before sending the appropriate credentials. If you are accessing a resource, which is known to be protected by authentication, you can configure the HttpState object to send credentials preemptively, obviating the need for the client to react to a 401 response code. In other words, the Authorization header is supplied in the initial request. To configure HttpClient to send credentials preemptively, retrieve an HttpClientParams object form HttpClient via getParams( ) method, and call setAuthenticationPreemptive(true) as follows:

HttpClientParams params = client.getParams( );
params.setAuthenticationPreemptive( true);

  Warning: Basic authentication involves sending an unencrypted password in the request. The value of the Authentication header in the request is simply testuser:crazypass sent through a Base64 encoding utility. If you are working on a system that uses Basic authentication, make sure that any system that performs authentication does so over SSL;otherwise, your password will fall into the wrong hands.

 1.10. NTLM Authentication

 1.10.1. Problem

  You need to access a resource that is protected by Microsoft's NTLM authentication protocol.

  1.10.2. Solution

  Create an instance of NTCredentials with a username, password, host, and domain,and setCredentials( ) on the HttpState associated with an instance of HttpClient. The following example demonstrates the use of NTCredentials to access a resource on host test.windowsmachine.com, which is on the domain TESTDOM:

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.methods.GetMethod;
HttpClient client = new HttpClient( );
//set credentials on the client
Credentials credentials = new NTCredentials (“testuser", ”crazypass","homecomputer","TESTDOM");
HttpState state = client.getState( );
state( ).setCredentials(null,null,credentials);
String url = "http://webmail.domain.biz/exchange/";
HttpMethod method = new GetMethod ( url );
client.executeMethod( method);
String response = method.getResponseBodyAsString( );
System.out.println( response);
method.releaseConnection( );

  1.10.3. Discussion

  The parameters to the constructor of NTCredentials are the username, the password, a hostname, and a domain. The hostname is the name of the machine making the request, and in this case, the third parameters is homecomputer. When this Credential object is set in the HttpState object, the first two parameter specify the authentication realm and the host to apply a Credential object to. The previous example sets both the authentication realm and the host to null; this makes the NTCredentials object the default Credentials to use if there is no realm or host specified. If we were using one instance of HttpClient to connect to two different hosts  with two different NTCredentials objects, both Credentials objects could be added to HttpState with the following code:

HttpClient client = new HttpClient( );
Credentials credentials1 = new NTCredentials( "testuser", "crazypass","homecomputer", "TESTDOM" );
Credentials credentials2 =new NTCredentials( "anotheruser", "password2","homecomputer", "DIFFERENT_DOMAIN" );
state( ).setCredentials( null, "webmail.domain.biz", credentials1 );
state( ).setCredentials( null, "silly-iis-server.lame.net", credentials2 );
// Execute a request which uses credentials1
String url = "http://webmail.domain.biz/exchange/";
HttpMethod method = new GetMethod( url );
client.executeMethod( method );
// Execute a request which uses credentials2
String url2 = "http://silly-iis-server.lame.net/test/";
HttpMethod method2 = new GetMethod( url2 );
client.executeMethod( method2 );

  The host webmail.domain.biz tries to authenticate the first request against the TESTDOM domain, and the silly-iis-server.lame.net host tries to authenticate the second request against the DIFFERENT_DOMAIN domain. Since the HttpState is configured with two separate Credentials objects for different hosts, both requests are successfully authenticated.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值