JAX-WS Sharepoint 401 NTLM no autorizado

Intento acceder a una lista Sharepoint a través de JAX-WS como se describe aquí

Sin embargo, cuando ejecuto el código a continuación, obtengo:

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

Sharepoint requiere autenticación NTLM. ¿Cuál puede ser el problema? ¡Muchas gracias!

 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; } 

Estaba enfrentando el mismo problema al conectarme con JAX-WS para intercambiar servicios web, y esto es lo que funcionó para mí:

Primero, crea un autenticador:

 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)); } } 

En su aplicación, configure el autenticador como predeterminado:

 String username = "DOMAIN\\USERNAME"; String password = "PASSWORD" NtlmAuthenticator authenticator = new NtlmAuthenticator(username, password); Authenticator.setDefault(authenticator); 

Tenga en cuenta que estoy utilizando el método n. ° 2 para especificar el dominio tal como se describe en la documentación de Java.

Según mis aprendizajes, la anulación de los parámetros de BindingProvider NO establece el nombre de usuario y la contraseña requeridos. La forma más sencilla de demostrar esto es que no hay forma de pasar el nombre de dominio a través de la anulación de BP.

He visto varias publicaciones en Internet que sugieren una manera similar a la sugerencia de Marcel Levy de utilizar una instancia de autenticador NTLM (que es la manera definida según la documentación de JAVA 6 disponible de Oracle). Pero, esta solución no me funcionó (estaba desarrollando un progtwig independiente independiente de cualquier lógica de servidor de aplicaciones).

Busqué en Google y probé muchas soluciones para este problema … aparentemente el código más simple que funcionó es el siguiente usando la biblioteca 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(); 

Aparentemente, CXF 3.0 no tiene una forma válida de configurar el cliente HTTP (4.3.x) con la instancia NTCredentials. Consulte el error https://issues.apache.org/jira/browse/CXF-5671


Por cierto, si tiene un mensaje simple que necesita ser transmitido, simplemente use HTTP Client (trabajé usando 4.3.4 .. no estoy seguro de las versiones anteriores) con Instancia NTCredentials. Eso también hizo la magia para mí. La muestra es la siguiente:

  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(); 

Por lo que sé, no puede realizar la autenticación NTLM a través de BindingProvider.

Si está familiarizado con Spring framework, puede usar Spring-WS . Spring-WS admite el transporte con Apache HttpClient 4.x a través de la clase HttpComponentsMessageSender. Apache HttpClient 4.x tiene un buen soporte para la autenticación NTLM. Puede utilizar las clases JAX-WS generadas por la herramienta wsimport como argumento para marshalSendAndReceive .

    Intereting Posts