Альтернативы для библиотеки JCIFS NTLM - PullRequest
17 голосов
/ 23 февраля 2009

Есть ли альтернативы для библиотеки JCIFS NTLM?

Ответы [ 7 ]

11 голосов
/ 21 мая 2010

Вафля - https://github.com/dblock/waffle

Имеет фильтры, аутентификаторы, поддерживает Spring-Security и т. Д. Только для Windows, но не требует собственных DLL.

3 голосов
/ 15 декабря 2015

На самом деле jcifs - это хорошо, и вы можете легко протестировать 4-стороннее рукопожатие локально с Windows IIS и поддерживающим java Socket.

Этот псевдокод Apache 2004 года полезен для построения алгоритма с использованием jcifs с использованием generateType1Msg() и generateType3Msg(), даже Apache предлагает пример в качестве альтернативы HttpClient.

Старый код Apache от 2004 года работает, но аутентификация нестабильна, вы часто получаете HTTP/1.1 401 Unauthorized, также этот действительно старый код от Luigi Dragone больше не работает. С другой стороны, HttpClient Apache работает без сбоев, но рукопожатие выполняется за кулисами (для справки. HttpClient требует new NTCredentials() для определения аутентификации пользователя).

Вот пример для проверки рукопожатия локально на IIS, на порту 81 без домена. Вам необходимо соответствующим образом изменить заголовки host, port, user и password и HTTP, в конечном итоге WWW-Authenticate, если вы не используете IIS.

HTTP/1.1 200 OK означает, что аутентификация правильная, в противном случае вы получите HTTP/1.1 401 Unauthorized.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import jcifs.ntlmssp.NtlmFlags;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.util.Base64;

import org.apache.http.impl.auth.NTLMEngineException;

public class TestNTLM {

    public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException {
        Socket s = new Socket("127.0.0.1", 81);
        s.setKeepAlive(true);
        InputStream is = s.getInputStream();
        OutputStream os = s.getOutputStream();
        BufferedReader r = new BufferedReader(new InputStreamReader(is));
        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(os));

        String host = "127.0.0.1:81";
        String hostDomain = "";
        String user = "My_Windows_Username";
        String password = "My_Windows_Password";

        w.write("GET http://127.0.0.1:81/ HTTP/1.1\n");
        w.write("Host: 127.0.0.1:81\n");
        w.write("Authorization: NTLM " + TestNTLM.generateType1Msg(hostDomain, host) + "\n\n");
        System.out.println("[First Message Sent]");
        w.flush();

        String resp = "", line = "";
        int contentLength = 0;
        while((line = r.readLine()) != null){
            if(line.length() == 0)
                break;
            System.out.println(line);
            if(line.startsWith("Content-Length"))
                contentLength = Integer.parseInt(line.substring(line.indexOf(":") + 1).trim());
            else if(line.startsWith("WWW-Authenticate"))
                resp = line.substring(line.indexOf(":") + 1).trim();
        }
        r.skip(contentLength);

        System.out.println("\n[Second Message Received]");
        System.out.println("Proxy-Authenticate: " + resp);
        resp = resp.substring(resp.indexOf(" ")).trim();

        w.write("GET http://127.0.0.1:81/ HTTP/1.1\n");
        w.write("Host: 127.0.0.1:81\n");
        w.write("Authorization: NTLM " + TestNTLM.generateType3Msg(user, password, hostDomain, host, new String(resp)) + "\n\n");

        w.flush();
        System.out.println("\n[Third Message Sent]");

        while((line = r.readLine()) != null){
            System.out.println(line);
            if(line.length() == 0)
                break;
        }
    }

    private static final int TYPE_1_FLAGS = 
            NtlmFlags.NTLMSSP_NEGOTIATE_56 | 
            NtlmFlags.NTLMSSP_NEGOTIATE_128 | 
            NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | 
            NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | 
            NtlmFlags.NTLMSSP_REQUEST_TARGET;

    public static String generateType1Msg(final String domain, final String workstation)
            throws NTLMEngineException {
        final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
        return Base64.encode(type1Message.toByteArray());
    }

    public static String generateType3Msg(final String username, final String password,
            final String domain, final String workstation, final String challenge)
                    throws NTLMEngineException {
        Type2Message type2Message;
        try {
            type2Message = new Type2Message(Base64.decode(challenge));
        } catch (final IOException exception) {
            throw new NTLMEngineException("Invalid NTLM type 2 message", exception);
        }
        final int type2Flags = type2Message.getFlags();
        final int type3Flags = type2Flags
                & (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));
        final Type3Message type3Message = new Type3Message(type2Message, password, domain,
                username, workstation, type3Flags);
        return Base64.encode(type3Message.toByteArray());
    }
}
3 голосов
/ 19 июля 2009

Если честно, вы не должны искать один. Для ваших нужд SSO вы должны использовать надлежащие kerberos / SPNEGO вместо устаревшего NTLM.

Для этого вам не нужны специальные библиотеки, так как JVM уже включены для этого автоматически. Все, что вам нужно сделать, это правильно настроить приложение и политики безопасности JVM. Официальная документация от Sun должна предоставить вам всю необходимую информацию, просто перейдите в раздел «API безопасности».

2 голосов
/ 04 ноября 2009

Я думаю, что NTLM устарела в пользу Kerberos / SPNEGO. Взгляните на проект SPLEGO HTTP Servlet Filter *1001*, чтобы узнать, подходит ли он вам.

1 голос
/ 01 июня 2010

Если вы не возражаете против коммерчески упакованного продукта, посмотрите: Quest Single Sign On для Java , который обеспечивает поддержку SPNEGO / Kerberos (включая сайты и протоколы S4U), а также NTLM.

1 голос
/ 09 января 2010

Java Opensource Single Sign On (JOSSO) в http://www.josso.org/ У них есть страница о NTLM, хотя я не уверен, насколько хорошо это работает.

1 голос
/ 27 мая 2009

jespa www.ioplex.com - единственный, с кем я столкнулся Никогда не использовал его, хотя

...