Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP digest authentication with HttpUrlConnection

Tags:

java

I am trying to connect to the Tomcat Web Server on my machine using a digest authentication. I am using the memory realm of tomcat. Here is how the server is configured:

1) In server.xml:

<Realm className="org.apache.catalina.realm.MemoryRealm" digest="MD5" />

2) In tomcat-users.xml

<user username="testuser" password="81dc9bdb52d04dc20036dbd8313ed055" roles="test"/>

3) In web.xml of my web project:

<auth-method>DIGEST</auth-method>

As you can see I have specified as a digest method "MD5" and I have encryped the password using the digest.sh of Tomcat.

Here is my code on the client side:

private static void testGet() throws IOException {

    // Create a URL
    URL test = new URL("http://localhost:8080/TestWebProject/TestServlet");

    // Open a connection to the URL
    HttpURLConnection conn = (HttpURLConnection) test.openConnection();

    MessageDigest md5 = null;
    try {
      md5 = MessageDigest.getInstance("MD5");
    } catch(NoSuchAlgorithmException e) {
      e.printStackTrace();
    }

    // Digest password using the MD5 algorithm
    String password = "1234";
    md5.update(password.getBytes());
    String digestedPass = digest2HexString(md5.digest());

    // Set header "Authorization"
    String credentials = "testuser:" + digestedPass;
    conn.setRequestProperty("Authorization", "Digest " + credentials);

    // Print status code and message
    System.out.println("Test HTTP GET method:");
    System.out.println("Status code: " + conn.getResponseCode());
    System.out.println("Message: " + conn.getResponseMessage());
    System.out.println();

}

private static String digest2HexString(byte[] digest)
{
   String digestString="";
   int low, hi ;

   for(int i=0; i < digest.length; i++)
   {
      low =  ( digest[i] & 0x0f ) ;
      hi  =  ( (digest[i] & 0xf0)>>4 ) ;
      digestString += Integer.toHexString(hi);
      digestString += Integer.toHexString(low);
   }
   return digestString ;
}

I think that my client side code is ok and the configuration of the server, too. Though the server keeps sending me the status code 401 with message "Unauthorized". As I am not an experienced java developer, I want to ask if anyone has idea or sees an error in my implementation.

Thank you in advance!

like image 715
user485624 Avatar asked Oct 24 '10 14:10

user485624


People also ask

How do I get response message from HttpUrlConnection?

The getResponseMessage is a method of Java HttpURLConnection class. This method is used to get response code from HTTP response message. For example, if the response code from a server is HTTP/1.0 200 OK or HTTP/1.0 404 Not Found, it extracts the string OK and Not Found else returns null if HTTP is not valid.


3 Answers

Digest authentication is far more complex than just sending username:password (that is actually Basic authentication... and the username:password tuple needs to be Base64 encoded!).

You can read all about digest here.

If you're not required to use HttpUrlConnection take a look at these two projects:

  • Async Http Client (more mature)
  • Hotpotato (mine)

Both of them already support Digest (and other useful stuff) out of the box.

like image 186
biasedbit Avatar answered Sep 28 '22 10:09

biasedbit


HttpUrlConnection is OK for simple jobs, but if you want something with more advanced features (like digest authentication), I'd recommend Commons HTTP Client.

like image 43
Mike Baranczak Avatar answered Sep 28 '22 09:09

Mike Baranczak


I am able to get it done working following code, please let me know if i am missing something;

        DefaultHttpClient httpclient = new DefaultHttpClient();

        ResponseHandler<String> responseHandler = new BasicResponseHandler();

        httpclient.getCredentialsProvider().setCredentials(
                new AuthScope("localhost", 8080), 
                new UsernamePasswordCredentials("username", "password"));   

        HttpGet httpget = new HttpGet(urlStr);
         System.out.println("executing request" + httpget.getRequestLine());

        String response = httpclient.execute(httpget, responseHandler);
        System.out.println("Response :: " + response);
like image 39
Maths Avatar answered Sep 28 '22 11:09

Maths