在Java应用程序中使用NTLM身份validation

我想在我的Java应用程序中使用Windows NTLM身份validation来透明地validationIntranet用户。 如果使用浏览器(单点login),用户不应该注意到任何身份validation。

我发现了几个支持NTLM的库,但不知道使用哪一个:

  • http://spnego.sourceforge.net/
  • http://sourceforge.net/projects/ntlmv2auth/
  • http://jcifs.samba.org/
  • http://www.ioplex.com/jespa.html
  • http://www.luigidragone.com/software/ntlm-authentication-in-java/

任何build议从哪里开始?

在上面的列表中,只有ntlmv2-auth和Jespa支持NTLMv2。 Jespa是可行的,但商业。 ntlmv2-auth我没有尝试,但它是基于Liferay的代码,我见过的工作。

“ntlm-authentication-in-java”只是NTLMv1,它是旧的,不安全的,并且在人们升级到更新的Windows版本时在环境数量减少的情况下工作。 JCIFS曾经有一个NTLMv1 HTTP认证过滤器,但是它在后来的版本中被删除了,因为它被实现的方式相当于对不安全协议的中间人攻击(man-in-the-middle attack)。 ('ntlm-authentication-in-java'也是如此。)

“spnego”项目是Kerberos而不是NTLM。 如果你想复制完整的IWA,就像IIS一样,你需要同时支持NTLMv2和Kerberos('NTLM'auth,'Negotiate'auth,NTLMSSP-in-SPNego auth和NTLM-masquerading-as-Negotiate auth)。

路易吉·德拉戈内的剧本真的很老,似乎总是失败。

HttpURLConnection可以使用NTLM,如果你添加库jcifs ,这个例子适用于最新的jcifs-1.3.18 :

 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import org.apache.http.impl.auth.NTLMEngineException; public class TestNTLMConnection { public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException { // Method 1 : authentication in URL jcifs.Config.registerSmbURLHandler(); URL urlRequest = new URL("http://domain%5Cuser:pass@127.0.0.1/"); // or Method 2 : authentication via System.setProperty() // System.setProperty("http.auth.ntlm.domain", "domain"); // System.setProperty("jcifs.smb.client.domain", "domain"); // System.setProperty("jcifs.smb.client.username", "user"); // System.setProperty("jcifs.smb.client.password", "pass"); // Not verified // System.setProperty("jcifs.netbios.hostname", "host"); // System.setProperty("java.protocol.handler.pkgs", "jcifs"); // URL urlRequest = new URL("http://127.0.0.1:8180/simulate_get.php"); HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection(); StringBuilder response = new StringBuilder(); try { InputStream stream = conn.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(stream)); String str = ""; while ((str = in.readLine()) != null) { response.append(str); } in.close(); System.out.println(response); } catch(IOException err) { System.out.println(err); } finally { Map<String, String> msgResponse = new HashMap<String, String>(); for (int i = 0;; i++) { String headerName = conn.getHeaderFieldKey(i); String headerValue = conn.getHeaderField(i); if (headerName == null && headerValue == null) { break; } msgResponse.put(headerName == null ? "Method" : headerName, headerValue); } System.out.println(msgResponse); } } } 

如果你对每个握手的内容感到好奇,你可以在这个线程中找到另一个使用jcifs和Socket的例子。

相对从你给的名单,我会去与JCIFS 。 这个图书馆是成熟的,他们的文档是好的。 最重要的是他们有相当正规的发布,最后一个是2011年11月。

Personal Experience :与我尝试过的其他人(spnego和ntmv2auth)相比起步相当简单,

参考: https : //jcifs.samba.org/src/docs/faq.html#ntlmv2

问:jCIFS是否支持NTLMv2?
答:是的。 从1.3.0开始,JCIFS完全支持NTLMv2并默认使用它。

注意:以前包含在JCIFS中的NTLM HTTP SSO筛选器不能支持NTLMv2。