Reputation: 4249
I was reading this article, with the help of it I am able to find the username, domain name and hostname of the machine accessing my JSP Page, But Still I can't understand how to authenticate the user. Because in Firefox when I am accessing my JSP page and try to enter correct Username but wrong password, it authenticates the user.
So the prime concern is how can I authenticate the user with NTLM Protocol, i.e. once I have the username and password, I can make a LDAP request to authenticate the user, but here only Username of the person is known to server.
<%
String auth = request.getHeader("Authorization");
/*
* Client to Server - Get Page.
*/
if (auth == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
return;
}
/*
* Client to Server
GET ...
Authorization: NTLM <base64-encoded type-1-message>
Type 1 Message -
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 1 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | 0x03 | 0xb2 | 0 | 0 |
+-------+-------+-------+-------+
16: | domain length | domain length |
+-------+-------+-------+-------+
20: | domain offset | 0 | 0 |
+-------+-------+-------+-------+
24: | host length | host length |
+-------+-------+-------+-------+
28: | host offset | 0 | 0 |
+-------+-------+-------+-------+
32: | host string |
+ +
. .
. .
+ +-----------------+
| | domain string |
+-------------+ +
. .
. .
+-------+-------+-------+-------+
*/
if (auth.startsWith("NTLM ")) {
byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth
.substring(5));
int off = 0, length, offset;
String s;
s = new String(msg, 0, msg.length);
if (msg[8] == 1) {
off = 18;
byte z = 0;
/*
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 2 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
16: | message len | 0 | 0 |
+-------+-------+-------+-------+
20: | 0x01 | 0x82 | 0 | 0 |
+-------+-------+-------+-------+
24: | |
+ server nonce |
28: | |
+-------+-------+-------+-------+
32: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
36: | 0 | 0 | 0 | 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,
(byte) 1, (byte) 9, (byte) 0, (byte) 9,
(byte) 1, (byte) 9, (byte) 8, (byte) 9,
z, z, z, z,
z, z, z, z };
//
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM "
+ new sun.misc.BASE64Encoder().encodeBuffer(msg1)
.trim());
return;
}
/*
* Client sending type 3 message.
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 3 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | LM-resp len | LM-Resp len |
+-------+-------+-------+-------+
16: | LM-resp off | 0 | 0 |
+-------+-------+-------+-------+
20: | NT-resp len | NT-Resp len |
+-------+-------+-------+-------+
24: | NT-resp off | 0 | 0 |
+-------+-------+-------+-------+
28: | domain length | domain length |
+-------+-------+-------+-------+
32: | domain offset | 0 | 0 |
+-------+-------+-------+-------+
36: | user length | user length |
+-------+-------+-------+-------+
40: | user offset | 0 | 0 |
+-------+-------+-------+-------+
44: | host length | host length |
+-------+-------+-------+-------+
48: | host offset | 0 | 0 |
+-------+-------+-------+-------+
52: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
56: | message len | 0 | 0 |
+-------+-------+-------+-------+
60: | 0x01 | 0x82 | 0 | 0 |
+-------+-------+-------+-------+
64: | domain string |
+ +
. .
. .
+ +-------------------+
| | user string |
+-----------+ +
. .
. .
+ +-------------+
| | host string |
+-----------------+ +
. .
. .
+ +---------------------------+
| | LanManager-response |
+---+ +
. .
. .
+ +------------------+
| | NT-response |
+------------+ +
. .
. .
+-------+-------+-------+-------+
*/
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);
System.out.println("Host String - " + s + " ");
} else{
return;
}
/*
* Reading domain information
*/
length = msg[off + 1] * 256 + msg[off];
offset = msg[off + 3] * 256 + msg[off + 2];
s = new String(msg, offset, length);
System.out.println("Domain Name - " + s + " ");
/*
* Reading User Name information.
*/
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
s = new String(msg, offset, length);
System.out.println("User Name - " + s + " ");
Upvotes: 3
Views: 5959
Reputation: 2025
All you have to do is to follow this article to enable Firefox to use NTLM like IE and Chrome does!
Upvotes: 0
Reputation: 17846
NTLM authentication does not use a password, it uses a challenge-response protocol which requires a few server roundtrips.
In the second GET request, you respond with a server 'nonce' which is the authentication challenge received from the domain controller. On the third GET, you get the authentication response which you can validate with the challenge via the domain controller.
In your code, you use a hard-coded challenge (0x19091989), and completely ignore the response.
JCIFS has an implementation that actually finds a domain controller to handle the challenge and response in http://code.google.com/p/jcifs-fork/source/browse/trunk/jcifs/src/jcifs/http/NtlmHttpFilter.java. You could reverse engineer this, or use the filter 'an sich' as described in http://jcifs.samba.org/src/docs/ntlmhttpauth.html. AFAIK this only works on a Windows server, but I could be mistaken.
Upvotes: 2
Reputation: 1750
In the following thread they put the Tomcat behind an Apache Server and use an Apache Module to perform the NTLM authentication.
Spring 3 and NTLM authentication
Upvotes: 1