11.11. NTLM Authentication

Problem

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

Solution

Create an instance of NTCredentials with a username, password, host, and domain, and call 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( );

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 parameter is homecomputer. When this Credential object is set in the HttpState object, the first two parameters 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" );

HttpState state = client.getState( );
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.

See Also

No one will dispute the assertion that the HTTP protocol has dramatically changed the world we live in, and one of the reasons for this success is the openness of the protocol. Unfortunately, NTLM is proprietary and undocumented, and this is reason enough to avoid using it entirely. If you are stuck with NTLM and you want to learn more about the protocol, it is described in excruciating detail at http://www.innovation.ch/java/ntlm.html and http://davenport.sourceforge.net/ntlm.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.200.109