Проверка аутентификации NTLMv2 в Java

Итак, я пытаюсь отследить странную ошибку с NTLMv2 и Java. Похоже, что NTLM игнорирует любую информацию, которую я передаю во время аутентификации на основе Java, и находит информацию где-то еще. Из-за этого NTLM будет аутентифицироваться на моем компьютере, даже если я предоставлю неверную информацию, и не будет работать на любом другом компьютере, даже если предоставлена ​​правильная информация. Конечной точкой является API веб-сервиса MOSS 2007, если это уместно.

Вот процесс, который я использую для аутентификации:

1) Передайте целевой сайт и данные для входа.

try {
    JLists list = new JLists(siteUrl, DEFAULT_SP_USERNAME,
        DEFAULT_SP_PASSWORD);
    list.addList(name, description, 101);

} catch (Exception e) {
     e.printStackTrace();
}


2) Установите аутентификатор по умолчанию на мой собственный NTLMAuthenticator, создайте заглушку службы и передайте информацию для входа.

public JLists(String siteURI, String username, String password)
        throws Exception {

    String endpointURI = siteURI + "/_vti_bin/Lists.asmx";

    Authenticator.setDefault(new NtlmAuthenticator(username, password));

    port = sharePointListsAuth(username, password);
    BindingProvider bp = (BindingProvider) port;
    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            endpointURI);
}

private ListsSoap sharePointListsAuth(String userName, String password) throws Exception {
    ListsSoap port = null;
    if (userName != null && password != null) {
        try {
            service = new Lists();
            port = service.getListsSoap();
            ((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName);
            ((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
        } catch (Exception e) {
            throw new Exception("Error: " + e.toString());
        }
    } else {
        throw new Exception("Couldn't authenticate: Invalid connection details given.");
    }
    return port;
}


Вот также копия класса NTLMAuthenticator:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

class NtlmAuthenticator extends Authenticator {

  private final String username;
  private final char[] password;

  public NtlmAuthenticator(final String username, final String password) {
    super();
    this.username = username;
    this.password = password.toCharArray(); 
  }

  public PasswordAuthentication getPasswordAuthentication() {
    return (new PasswordAuthentication (username, password));
  }
}

3) Позвоните в мою службу. У меня на самом деле нет никаких проблем в этой части, но если кому-то нужен код, я тоже его опубликую.

Я чувствую, что Java каким-то образом ссылается на мою информацию Active Directory и использует вместо нее предоставленную информацию, но я понятия не имею, в какой момент это произойдет.


person WLPhoenix    schedule 22.06.2012    source источник
comment
Я использовал Wireshark, чтобы убедиться, что соединение действительно создано с использованием NTLM и без проблем аутентифицируется в стандартной трехэтапной процедуре NTLM, даже если указано неверное имя пользователя/пароль.   -  person WLPhoenix    schedule 22.06.2012


Ответы (2)


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

Кажется, нет способа обойти это без декомпиляции исходного кода Java и самостоятельного изменения этой переменной, но, к счастью, в конечном случае для моего приложения это не понадобится.

person WLPhoenix    schedule 25.06.2012
comment
Есть способ изменить код, но он не для производства stackoverflow.com/a/9024765/14811 - person Jonathan Barbero; 03.09.2012

вы можете предоставить свой собственный

public class Handler extends jdk6.sun.net.www.protocol.http.Handler

который с некоторым размышлением вы можете получить поля класса HttpURLConnection и изменить его.

field.setAccessible( true );
field.setBoolean( connection, false );

поля «tryTransparentNTLMServer» и «tryTransparentNTLMProxy»;

person tfforums    schedule 20.03.2014