I try to access a Sharepoint list via JAX-WS as described here
However, when running the code below I get:
java.lang.Exception: Exception. See stacktrace.com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized
Sharepoint requires NTLM authentication. What may be the problem? Thanks a lot!
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;
}
Based on my learnings, overriding the BindingProvider parameters does NOT set the required username and password. The simplest way to prove this is that there is no way to pass the domain name through the BP override.
I've seen multiple posts over the internet suggesting a way similar to Marcel Levy's suggestion in above to use an NTLM authenticator instance (Which is the way defined as per JAVA 6 documentation available from Oracle). But, this solution did not work for me (I was developing a standalone program independent of any application server logic).
I googled and tried a lot of solutions to this problem.. apparently the simplest code that worked is as below using the JCIFS library
Apparently CXF 3.0 doesnt have a valid way of configuring the HTTP Client (4.3.x) with NTCredentials instance. Please refer to bug https://issues.apache.org/jira/browse/CXF-5671
By the way, if you have a simple message which needs to be transmitted, just use HTTP Client (I worked using 4.3.4.. not sure of the earlier versions) with NTCredentials Instance. That too did the magic for me.. The sample is as below:
I was facing the same problem when connecting with JAX-WS to Exchange web services, and here's what worked for me:
First, create an authenticator:
In your application, set up the authenticator as the default:
Note that I'm using method #2 for specifying the domain as described in the Java documentation.
As far as I know, you can't do NTLM authentication through BindingProvider.
If you are familiar with Spring framework, you can use Spring-WS. Spring-WS supports transport with Apache HttpClient 4.x through the HttpComponentsMessageSender class. Apache HttpClient 4.x has good support for NTLM authentication. You can use the JAX-WS classes generated by wsimport tool as argument to marshalSendAndReceive.