JAX-WS Sharepoint 401 Несанкционированный NTLM - PullRequest
13 голосов
/ 01 февраля 2011

Я пытаюсь получить доступ к списку Sharepoint через JAX-WS, как описано здесь

Однако при выполнении кода ниже я получаю:

java.lang.Exception: Exception. See stacktrace.com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized

Sharepoint требуетсяNTLM аутентификация.В чем может быть проблема?Большое спасибо!

public static ListsSoap sharePointListsAuth(String userName, String password) throws Exception {
    ListsSoap port = null;
    if (userName != null && password != null) {
        try {
            Lists service = new Lists();
            port = service.getListsSoap();
            System.out.println("Web Service Auth Username: " + userName);
            ((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;
}

Ответы [ 3 ]

17 голосов
/ 13 мая 2011

Я столкнулся с той же проблемой при подключении с JAX-WS к веб-сервисам Exchange, и вот что сработало для меня:

Сначала создайте аутентификатор:

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

public class NtlmAuthenticator extends Authenticator {

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

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

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

В вашем приложении установите аутентификатор по умолчанию:

String username = "DOMAIN\\USERNAME";
String password = "PASSWORD"

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

Обратите внимание, что я использую метод # 2 для указания домена, как описано в документации Java.

2 голосов
/ 23 июня 2014

Исходя из моих знаний, переопределение параметров BindingProvider НЕ устанавливает требуемые имя пользователя и пароль. Самый простой способ доказать это состоит в том, что нет никакого способа передать доменное имя через переопределение BP.

Я видел несколько публикаций в Интернете, предлагающих способ, аналогичный предложенному Марселем Леви выше, использовать экземпляр аутентификатора NTLM (который определен в соответствии с документацией JAVA 6, доступной в Oracle). Но это решение не сработало для меня (я разрабатывал отдельную программу, независимую от логики сервера приложений).

Я погуглил и попробовал множество решений этой проблемы .. очевидно, самый простой код, который работает, как показано ниже, с использованием библиотеки JCIFS

    //Set the jcifs properties
    jcifs.Config.setProperty("jcifs.smb.client.domain", "domainname");
    jcifs.Config.setProperty("jcifs.netbios.wins", "xxx.xxx.xxx.xxx");
    jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "300000"); // 5 minutes
    jcifs.Config.setProperty("jcifs.netbios.cachePolicy", "1200"); // 20 minutes
    jcifs.Config.setProperty("jcifs.smb.client.username", "username");
    jcifs.Config.setProperty("jcifs.smb.client.password", "password");

    //Register the jcifs URL handler to enable NTLM
    jcifs.Config.registerSmbURLHandler();

Очевидно, что в CXF 3.0 нет допустимого способа настройки HTTP-клиента (4.3.x) с экземпляром NTCredentials. Пожалуйста, обратитесь к ошибке https://issues.apache.org/jira/browse/CXF-5671


Кстати, если у вас есть простое сообщение, которое нужно передать, просто используйте HTTP Client (я работал с 4.3.4 .. не уверен в более ранних версиях) с экземпляром NTCredentials. Это тоже сделало магию для меня .. Пример, как показано ниже:

    final NTCredentials ntCredentials = new NTCredentials("username", "Passworrd","destination", "domain");
    CredentialsProvider credsProvider = new BasicCredentialsProvider();

    credsProvider.setCredentials(AuthScope.ANY, ntCredentials);
    CloseableHttpClient httpclient = HttpClientBuilder.create()
                                        .setDefaultCredentialsProvider(credsProvider)
                                        .build();
1 голос
/ 18 июня 2012

Насколько я знаю, вы не можете выполнить NTLM-аутентификацию через BindingProvider.

Если вы знакомы с Spring Framework, вы можете использовать Spring-WS . Spring-WS поддерживает транспорт с Apache HttpClient 4.x через класс HttpComponentsMessageSender. Apache HttpClient 4.x имеет хорошую поддержку аутентификации NTLM. Вы можете использовать классы JAX-WS, сгенерированные инструментом wsimport, в качестве аргумента для marshalSendAndReceive .

...