This week's giveaway is in the EJB and other Java EE Technologies forum.
We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line!
See this thread for details.
The moose likes Web Services and the fly likes Constantly getting a 401 with Java Sharepoint Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Web Services
Bookmark "Constantly getting a 401 with Java Sharepoint" Watch "Constantly getting a 401 with Java Sharepoint" New topic
Author

Constantly getting a 401 with Java Sharepoint

Michael Lee
Greenhorn

Joined: Dec 01, 2011
Posts: 6
Ok. I have no idea how to fix this. I've tried a million things. I want to just do the most BASIC of web services. I've compiled my wsdl using;
wsimport -p com.microsoft.schemas.sharepoint.soap -keep -extension lists.asmx.xml.wsdl

We had AD authentication but I've asked the Sharepoint guy to turn on basic auth instead and still nothing is working.
I have, what I think, is very simple code;

Lists service = new Lists();
listsSoap = service.getListsSoap();
((BindingProvider) listsSoap).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName);
((BindingProvider) listsSoap).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
((BindingProvider) listsSoap).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://hostname/_vti_bin/lists.asmx?WSDL");
GetListCollectionResult result = listsSoap.getListCollection();

I have to have the ability to change WHERE (endpoint) the sharepoint server is because it will change in production. That is the hostname address above. I have it as a parameter.
I've tried all kinds of variations. I've created an NTLMAuthenticator class when it was AD but that created a fatal java core dump! (I'm using jdk 1.7 5b3)

Is it because the WSDL itself is not authenticated? No idea. I've seen people say make it anonymous but I don't control what is on the production server.

The error is this;

09:55:54,370 DEBUG httpclient.wire.header - >> "POST /_vti_bin/lists.asmx?WSDL HTTP/1.1[\r][\n]"
09:55:54,411 DEBUG httpclient.wire.header - >> "Content-Type: text/xml; charset=UTF-8[\r][\n]"
09:55:54,411 DEBUG httpclient.wire.header - >> "SOAPAction: "http://schemas.microsoft.com/sharepoint/soap/GetListCollection"[\r][\n]"
09:55:54,412 DEBUG httpclient.wire.header - >> "User-Agent: Axis2[\r][\n]"
09:55:54,412 DEBUG httpclient.wire.header - >> "Authorization: Basic QVRMREVWLkNPTVxyeWFuLnJlZ2FuOjMyUCNyZEA=[\r][\n]"
09:55:54,412 DEBUG httpclient.wire.header - >> "Host: 172.16.17.229[\r][\n]"
09:55:54,413 DEBUG httpclient.wire.header - >> "Transfer-Encoding: chunked[\r][\n]"
09:55:54,413 DEBUG httpclient.wire.header - >> "[\r][\n]"
09:55:59,534 DEBUG httpclient.wire.content - >> "ec[\r][\n]"
09:55:59,535 DEBUG httpclient.wire.content - >> "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/"/></soapenv:Body></soapenv:Envelope>"
09:55:59,535 DEBUG httpclient.wire.content - >> "[\r][\n]"
09:55:59,536 DEBUG httpclient.wire.content - >> "0"
09:55:59,536 DEBUG httpclient.wire.content - >> "[\r][\n]"
09:55:59,536 DEBUG httpclient.wire.content - >> "[\r][\n]"
09:55:59,740 DEBUG httpclient.wire.header - << "HTTP/1.1 401 Unauthorized[\r][\n]"
09:55:59,741 DEBUG httpclient.wire.header - << "HTTP/1.1 401 Unauthorized[\r][\n]"
09:55:59,745 DEBUG httpclient.wire.header - << "Server: Microsoft-IIS/7.5[\r][\n]"
09:55:59,746 DEBUG httpclient.wire.header - << "SPRequestGuid: c5ac71b5-f43a-429c-b9bb-09b8d296aee1[\r][\n]"
09:55:59,747 DEBUG httpclient.wire.header - << "WWW-Authenticate: Negotiate[\r][\n]"
09:55:59,748 DEBUG httpclient.wire.header - << "WWW-Authenticate: NTLM[\r][\n]"
09:55:59,748 DEBUG httpclient.wire.header - << "X-Powered-By: ASP.NET[\r][\n]"
09:55:59,749 DEBUG httpclient.wire.header - << "MicrosoftSharePointTeamServices: 14.0.0.4762[\r][\n]"
09:55:59,750 DEBUG httpclient.wire.header - << "Date: Tue, 25 Sep 2012 14:00:26 GMT[\r][\n]"
09:55:59,751 DEBUG httpclient.wire.header - << "Content-Length: 0[\r][\n]"
09:55:59,751 DEBUG httpclient.wire.header - << "[\r][\n]"
09:55:59,765 ERROR .httpclient.HttpMethodDirector - Credentials cannot be used for NTLM authentication: org.apache.commons.httpclient.UsernamePasswordCredentials
org.apache.commons.httpclient.auth.InvalidCredentialsException: Credentials cannot be used for NTLM authentication: org.apache.commons.httpclient.UsernamePasswordCredentials
at org.apache.commons.httpclient.auth.NTLMScheme.authenticate(NTLMScheme.java:332)
at org.apache.commons.httpclient.HttpMethodDirector.authenticateHost(HttpMethodDirector.java:282)
at org.apache.commons.httpclient.HttpMethodDirector.authenticate(HttpMethodDirector.java:234)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
.....

Help me Obi Wan, you're my only hope.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18115
    
    8

Well, at the beginning I think I see you sending something to do with HTTP basic authentication. And then I think I see the server sending you a 401, saying that didn't authenticate. And then I think I see the server sending back a request to do NTLM authentication. And then I think I see you trying to do that but failing.

Does that match what you think you're seeing?

If so then it looks like you have two possibilities: (1) fix the basic authentication so it works (2) fix the NTLM authentication so it works. Sorry if that sounds facile or if it duplicates one of the millions of things you already tried, but perhaps it helps you to focus a bit.

Michael Lee
Greenhorn

Joined: Dec 01, 2011
Posts: 6
Thanks for the reply Paul. I have a questions. The server should be set to Basic auth. So why is it doing NTLM? Is that the problem?
Michael Lee
Greenhorn

Joined: Dec 01, 2011
Posts: 6
I think I may have found the problem. Our IIS was mis-configured. There are about 10 security settings that can each be set in about 10,000 different places in IIS. It looks like what was happening was Basic auth AND NTLM were BOTH turned on. What happens is, if you send credentials to NTLM, it says you DON'T need credentials. The NTLM mechanism is different than my method above. I think it is ticket based so it expects that in the header. Anyway, I turned off NTLM and just used basic auth. That 'appears' to be working. It looks like it's just retrieving the WSDL.
Now I'm getting this though;


java.lang.Exception: Error: javax.xml.ws.soap.SOAPFaultException: org.apache.axiom.soap.SOAPProcessingException: First Element must contain the local name, Envelope , but found definitions
at com.exxova.mybi.SharepointService.sharePointListsAuth(SharepointService.java:219)
Michael Lee
Greenhorn

Joined: Dec 01, 2011
Posts: 6
The problem is I can't even put in the URL of the web service! I get a 401 right out of the gate! The WSDL is obviously secured. So how do I get around this?

URL wsdlLocation = new URL("http://"+host+"/_vti_bin/lists.asmx?WSDL");
QName qname = new QName("http://schemas.microsoft.com/sharepoint/soap/", "GetListItems");
Lists service = (Lists) Lists.create(wsdlLocation, qname);

I'm starting to think no one has done Java->Sharepoint with Authentication turned on. I see NO working code.
Michael Lee
Greenhorn

Joined: Dec 01, 2011
Posts: 6
I see TONS of posts similar to mine but none seem to have a solution
This is WAY too complicated!

Here is my insanely awful 'design'.

http://tinypic.com/r/2ibzxiv/6

This is what we have to deal with. Literally we can set this up on a multitude of Sharepoint servers. Our app is configurable so we can set whatever we want easily but it has to handle sharepoint 2007 or 2010, any auth it supports, and the credentials of the user come through our Tomcat server somehow from the user. This is either username/password or, maybe, automagically through the header?! I have no idea. Nothing is working and I don't see any real world examples that address what seems to be the main real world scenario.
I compile the WSDL on the file system, not the server. It is part of an eclipse project and I use a wsimport script to generate the code. The Sharepoint server can exist 'wherever' so the host, port, etc are variables. If I pass the URL in for the WSDL (endpoint?) then I get the 401 above BEFORE I can even send credentials for basic auth! Keep in mind I may need other auth methods. If JDK 1.6 is needed for NTLM2 support then we can dump Tomcat 5.5 as one of the requirements if need be.

How has ANYONE gotten this to work?
t field
Greenhorn

Joined: Aug 21, 2008
Posts: 2
so firstly.... store the wsdl locally then override the end point...
then use the authenticator class to do the dirty work

//twist - java 7 is actually changing this i think

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Constantly getting a 401 with Java Sharepoint
 
Similar Threads
Attempt to retrieve Sharepoint WSDL fails with “Server redirected too many times”
Sharepoint Webservice call from Java Client returns 403-Forbidden
Nondescript "Unsupported Content-Type" error when connecting to https Sharepoint web services
Problem with Axis2 via proxy with NTLM authentication (currently defaulting to BASIC)
Consume Sharepoint Web Service from inside code