Get username using NT Challenge (NTLM)Tag(s): Security
Even if the application server do not support NTLM protocol, it is possible to use it to extract the Windows username. From the server, we ask the browser to identify the current user, and "by hand", we extract the response from the answer.
The browser client must support NT Challenge authentification mechanism (IE does).
This is a quick HACK to extract the username! There is no security into this. Beware...
[username.jsp]
<%@ page import="sun.misc.BASE64Encoder" %> <p><h1>Network Windows USERNAME without any login (ie)</h1></p> <% String auth = request.getHeader("Authorization"); if (auth == null) { response.setStatus(response.SC_UNAUTHORIZED); response.setHeader("WWW-Authenticate", "NTLM"); return; } if (auth.startsWith("NTLM ")) { byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5)); int off = 0, length, offset; String s; 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}; // 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+18]; s = new String(msg, offset, length); //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); //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 <span style='position:relative; width:190;" + " height:10;filter:glow(Color=#009966,Strength=1)'>"); out.println(s + "</SPAN>"); } %></BODY>
NOTES:
A comment from Weijun Ji : This technique only works if a user has its IE browser security setting
set at middle/low (or if the server is trusted like in an intranet environment).
With this setting, browser will grab login username
automatically. If the security setting is at high, then a window will
prompt user for input. At that time, whatever username the user put in will
be passed to the "NTLM program". Since the user is not authenticated,
you have no way to know if this user is a true user or not. In this way, any
user can pretend to be anybody else as long as he has his security level set
as high.
A comment from A. Santana : It didn't work for Firefox, so I did a silly workaround in the midtime. I removed everything is not a word or space... look: s.replaceAll("[^a-zA-Z\s]","");
You want to deeper into this subject, take a look at these sites :
http://www.innovation.ch/java/ntlm.html
http://free.tagish.net/jaas/index.jsp
http://www.luigidragone.com/networking/ntlm.html
Starting from jdk1.4.2, Sun provides support for NTLM, see http://java.sun.com/j2se/1.4.2/changes.html#networking
For a complete solution see JCIFS (for Tomcat and others) at http://jcifs.samba.org