Использование аутентификации NTLM в приложениях Java
Я хочу использовать аутентификацию Windows NTLM в своем Java-приложении для прозрачной аутентификации пользователей интрасети. Пользователи не должны замечать никакой аутентификации при использовании своих браузеров (единый вход).
Я нашел несколько библиотек с поддержкой 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/
Есть предложения, с чего начать?
4 ответа:
Из приведенного выше списка только ntlmv2-auth и Jespa поддерживают NTLMv2. Jespa работоспособна, но коммерчна. ntlmv2-auth я не пробовал, но он основан на коде из Liferay, который я видел работающим раньше.
"ntlm-authentication-in-java" - это только NTLMv1, который является старым, небезопасным и работает в уменьшающемся числе сред по мере обновления до новых версий Windows. JCIFS раньше имел фильтр ntlmv1 HTTP auth, но он был удален в более поздних версиях, так как он был реализован это равносильно атаке "человек в середине" на небезопасный протокол. (То же самое, по-видимому, верно и для "ntlm-authentication-in-java".)
Проект "spnego" - это Kerberos, а не NTLM. Если вы хотите повторить полный Ива как IIS делает это, вы должны были бы поддерживать оба NTLMv2 и Kerberos ('протокол NTLM' авт, "согласование" авт, службы ntlmssp-в-содержит двиг и NTLM-маскарад-как договориться авт).
Сценарий Луиджи Драгоне действительно стар и, кажется, всегда терпит неудачу.
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 и сокет на этом потоке.
Относительно из списка,который вы дали, я бы пошел сJCIFS . Библиотека зрелая, и документация у них хорошая. В довершение всего у них были довольно регулярные релизы, и последний из них был в ноябре 2011 года.
Personal Experience
: это было довольно легко начать, когда по сравнению с другими, которые я пробовал (spnego и ntmv2auth)
Ref: https://jcifs.samba.org/src/docs/faq.html#ntlmv2
Вопрос: поддерживает ли jCIFS NTLMv2?
Ответ: Да. Начиная с версии 1.3.0, JCIFS полностью поддерживает NTLMv2 и использует его по умолчанию.Примечание: фильтр NTLM HTTP SSO, который раньше включался в JCIFS, не может поддерживать NTLMv2.