Использование аутентификации NTLM в приложениях Java


Я хочу использовать аутентификацию Windows NTLM в своем Java-приложении для прозрачной аутентификации пользователей интрасети. Пользователи не должны замечать никакой аутентификации при использовании своих браузеров (единый вход).

Я нашел несколько библиотек с поддержкой NTLM, но не знаю, какую из них использование:

Есть предложения, с чего начать?

4 11

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.