我有一个使用SSO的网站,它正在使用NTLM身份验证,到目前为止在XP和win 7(32位)上工作得很好,但最近我公司决定使用win 7(64位)计算机。在这些PC上,握手在类型2消息之后结束,而tomcat返回401.我不知道如何调查,也许这里有人可以给我一些提示。
这是在servlet的doPost方法中:
try {
// NTLM Handshake
// 1: Client --> Server | GET ...
// 2: Client <-- Server | 401 Unauthorized/WWW-Authenticate: NTLM
String auth = request.getHeader("Authorization");
if (auth == null) {
response.setStatus(response.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
response.flushBuffer();
return;
}
if (auth.startsWith("NTLM ")) {
byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth
.substring(5));
int off = 0, length, offset;
// 3: Client --> Server | GET .../Authorization: NTLM
// <base64-encoded type-1-message>
if (msg[8] == 1) {
// 4: Client <-- Server | 401 Unauthorized/WWW-Authenticate:
// NTLM <base64-encoded type-2-message>
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.setHeader("WWW-Authenticate", "NTLM "
+ new sun.misc.BASE64Encoder().encodeBuffer(msg1));
//response.sendError(response.SC_UNAUTHORIZED);
response.setStatus(response.SC_UNAUTHORIZED);
response.flushBuffer();
return;
}
// 5: Client --> Server | GET .../Authorization: NTLM
// <base64-encoded type-3-message>
else if (msg[8] == 3) {
off = 30;
length = msg[off + 17] * 256 + msg[off + 16];
offset = msg[off + 19] * 256 + msg[off + 18];
String remoteHost = new String(msg, offset, length);
length = msg[off + 1] * 256 + msg[off];
offset = msg[off + 3] * 256 + msg[off + 2];
String domain = new String(msg, offset, length);
for (int i = 0; i < domain.length(); i += 2)
loginDomain += domain.charAt(i);
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
String username = new String(msg, offset, length);
for (int i = 0; i < username.length(); i += 2)
loginUser += username.charAt(i);
}
}
} catch (Exception se) {
log.error(loginUser + ", NTLM handshake exception:", se);
}
答案 0 :(得分:2)
这是64位PC上的政策问题,因为NTLMv2被迫。解决方案是在安全策略中禁用这些设置。
•运行“secpol.msc”这将打开一个标题为“本地安全策略”的窗口
•安全设置&gt;本地政策&gt;安全选项&gt; “网络安全:基于NTLM SSP的最低会话安全性......”
有两个类似的条目从这样开始,打开并取消选中“需要NTLMv2会话安全性”。
至少我们发现我们正在使用NTLMv1。 :|
答案 1 :(得分:2)
试试这个
使用以下代码启用NTLM扩展安全性
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, **(byte) 8**, z, z, (byte) 2, (byte) 2,
(byte) 2, z, z, z, z, z, z, z, z, z, z, z, z
};
答案 2 :(得分:1)
如果您仍想坚持使用JCIFS,请尝试使用这些链接来克服“无效参数错误”和“无法与合适的域控制器协商”。 它适用于NTLM,但不保证更安全地使用NTLMv2。
“参数无效” https://www.sysaid.com/Sysforums/posts/list/9065.page。
“无法与合适的域控制器协商” https://lists.samba.org/archive/jcifs/2005-August/005312.html
答案 3 :(得分:0)
大多数企业网络都将转移到NTLMv2。我们不久前遇到了这个问题,并从http://www.ioplex.com/获得了Jespa。只要你有一个Servlet堆栈,它就可以正常工作。如果您正在使用像Play这样的非Java EE堆栈,除了拒绝对NTLMv1的支持之外,我不知道其他解决方案。