Categories
Coding

JDK-Based NTLM Authentication

When Sun released the 1.4.2 version of the JDK, they slipped in support for native NTLM authentication on Windows. This is done by retrieving the logged-on user’s username and password from the OS whenever an NTLM challenge is received. The only information that needs to be supplied is the NT domain. Here is an example that authenticates through an MS proxy, using my currently active credentials.


package uk.co.researchkitchen.ntlm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class TestJDKNTLM {

    private void execute() throws IOException {
        System.setProperty("proxySet""true");
        System.setProperty("http.proxyHost""proxy1.researchkitchen.co.uk");
        System.setProperty("http.proxyPort""8080");
        System.setProperty("http.auth.ntlm.domain""MYDOMAIN");

        URL url = new URL("http://www.yahoo.com");
        URLConnection conn = url.openConnection();

        conn.setAllowUserInteraction(true);
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        int read = 0;
        String body = null;

        do {
          body = reader.readLine();
          System.out.println(body);
        while (body != null);

    }

    public static void main(String[] argsthrows IOException {
        new TestJDKNTLM().execute();
    }

}

Categories
Coding

NTLM Proxy Authentication and Jakarta HttpClient

In my current work environment, our Web access is proxied via a MS ISA server, which uses NTML proxy authentication. I was recently looking at NTLM proxy authentication, as I had problems running Subversion inside the proxy (this should be fixed now with the newest release of Neon, Subversion’s WebDAV layer). I am currently looking at some NTLM providers in the Java space, and one of the obvious ones I came across is the Jakarta HttpClient. Here is an example that will authenticate to an NTLM-based proxy. The code is for HttpClient 3.0-RC2.


package uk.co.researchkitchen.ntlm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;

public class TestNTLM {

    private void execute() throws HttpException, IOException {
        HttpClient proxyclient = new HttpClient();

        proxyclient.getHostConfiguration().setHost("www.yahoo.com");
        proxyclient.getHostConfiguration().setProxy("lproxyhost.researchkitchen.co.uk"8080);


        List authPrefs = new ArrayList();
        authPrefs.add(AuthPolicy.NTLM);

        proxyclient.getState().setProxyCredentials(
            new AuthScope(null, 8080null),
            new NTCredentials("username""password""""MYDOMAIN"));

        proxyclient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);

        GetMethod get = new GetMethod("/");
        int status = proxyclient.executeMethod(get);

        System.out.println(status);

        BufferedReader bis = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));

        int count = 0;
        int read = 0;
        System.out.println("Content length: " + get.getResponseContentLength());
        char[] body = new char[2048];
        do {
          count = bis.read(body);
          read += count;
          System.out.println(body);
        while (count != -1);

        System.out.println("Read " + read + " bytes");
    }


    public static void main(String[] argsthrows HttpException, IOException {
        new TestNTLM().execute();
    }

}
Categories
Coding

Eclipse 3.1M6 and package-info

Another issue this time with Eclipse 3.1 M6. This concerns the “package-info” mechanism for package-level annotations. We are using package-info.java to declare a package-level sequence generator:


@javax.persistence.SequenceGenerator(
      name="SEQ_GEN",
      sequenceName="SQ_CDB_IDS"
  )

package uk.co.researchkitchen.hibernate;

This seems to compile OK, but when I try to run some unit tests, it chokes:


org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'test.sessionFactory' defined in class path resource [application_test_context.xml]: Initialization of bean failed; nested exception is java.lang.ClassFormatError: Illegal class modifiers in class uk/co/researchkitchen/hibernate/package-info: 0x1600
java.lang.ClassFormatError: Illegal class modifiers in class uk/co/researchkitchen/hibernate/package-info: 0x1600
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:102)
at org.hibernate.cfg.AnnotationBinder.bindPackage(AnnotationBinder.java:141)
at org.hibernate.cfg.AnnotationConfiguration.addPackage(AnnotationConfiguration.java:115)
...

Apparently, support for the package-info mechanism has been added in M6. I’m presuming this is an Eclipse issue as colleagues using IDEA have no such issues.