NTLM Authentication in Java


In one of my previous lives, I used to work in Microsoft and there this word – NTLM (NT Lan Manager) was something that came to us whenever we used to work on applications. Microsoft OS have always provided us with an inbuilt security systems that can be effectively used to offer authentication (and even authorization to web applications).

Many years back, I moved over into Java world and when I was asked to carry out my very first security implementation, I realized that there was no easy way to do this and many clients would actually want us to use LDAP for authentication and authorization. For many years, I continued to use that. And, then one day in a discussion with a client, we were asked to offer SSO implementation and client did not have an existing setup like SiteMinder. I started to think about if we can go about using NTLM based authentication. The reason that was possible was because the application we were asked to build was to be used within the organization itself and all the people were required to login into a domain.

After some research, I was able to find out a way we could do this. We did a POC and showed it to the client and they were happy about it. What we did has been explained below:

  • Wrote a Servlet which was the first one to be loaded (like Authentication Interceptor). This servlet was responsible for reading the header attributes and identify the user’s Domain and NTID
  • Once we had the details; we sent a request to our Database to see if that user is registered under the same domain/NTID
  • If the user was found in our user-database we allowed him to pass through
  • And then roles and authorization for user was loaded

Basically, we bypassed the “Login Screen” where the user was entering the password and used Domain information. Please note that it was possible for us because the Client guaranteed that there was this domain always and all users had unique NTIDs. Also, that it was their responsibility to shield the application from any external entry points where someone may impersonate the Domain/ID.

If you are interested, you can refer to the code below:

<%@ page import="sun.misc.BASE64Encoder" %>
<%
String auth = request.getHeader("Authorization");
String s = "";

//no auth, request NTLM
if (auth == null)
{
        response.setStatus(response.SC_UNAUTHORIZED);
        response.setHeader("WWW-Authenticate", "NTLM");
        return;
}

//check what client sent
if (auth.startsWith("NTLM "))
{
        byte[] msg =
           new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
        int off = 0, length, offset;

        if (msg[8] == 1) {
            off = 18;

            byte z = 0;
            byte[] msg1 =
                {(byte)'N', (byte)'T', (byte)'L', (byte)'M', (byte)'S',(byte)'S', (byte)'P',
                z,(byte)2, z, z, z, z, z, z, z,
                (byte)40, z, z, z, (byte)1, (byte)130, z, z,
                z, (byte)2, (byte)2, (byte)2, z, z, z, z, //
                z, z, z, z, z, z, z, z};
            // send ntlm type2 msg

            response.setStatus(response.SC_UNAUTHORIZED);
            response.setHeader("WWW-Authenticate", "NTLM "
               + new sun.misc.BASE64Encoder().encodeBuffer(msg1).trim());

               return;
        }
        else if (msg[8] == 3) {
                off = 30;
                length = msg[off+17]*256 + msg[off+16];
                offset = msg[off+19]*256 + msg[off+8];
                s = new String(msg, offset, length);
                // print computer name // out.println(s + " ");
        }
        else
        return;

        length = msg[off+1]*256 + msg[off];
        offset = msg[off+3]*256 + msg[off+2];
        s = new String(msg, offset, length);
        //domain//out.println(s + " ");
        length = msg[off+9]*256 + msg[off+8];
        offset = msg[off+11]*256 + msg[off+10];

        s = new String(msg, offset, length);
        out.println("Hello  "); out.println(s + "");
}
%>

6 thoughts on “NTLM Authentication in Java

  1. Hi…The same thing i m implementing but i m struggling with a thing that as per my requirement is the ntid passowrd should not be cached in the user machine…is there any way for this..please help……………………………………………

      1. Hello Kapil, I am trying to see how we can integrate NTLM authentication with AD. If you have any POC, can you share Since I need to see how this works?

        Thanks
        Reddy

  2. Hello Kapil,

    Thanks for putting this aricle. The solution mentioned here has come as a great help to me. I have learnt a lot from you, thanks for all help and guidance.

    Please keep posting such interesting things.

    Best,
    Chandan Arora

Initiate your idea here...