我正在阅读这篇文章,在它的帮助下,我能够找到访问我的 JSP 页面的机器的用户名、域名和主机名,但我仍然不明白如何验证用户身份。因为在 Firefox 中,当我访问我的 JSP 页面并尝试输入正确的用户名但密码错误时,它会对用户进行身份验证。
所以主要关心的是如何使用 NTLM 协议对用户进行身份验证,即一旦我有了用户名和密码,我就可以发出 LDAP 请求来验证用户身份,但这里只有该人的用户名对服务器是已知的。
<%
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 + " ");