Hi!

I too did a lot of research on the internet regarding this http header field 
... and didn't find something which defines a correct behavior for the server 
during the negotiation phase.
The two phases the NTLM requires is a Microsoft extension, covered in many 
details, but not able to answer this special question.

Though, the first 401 response is definitely allowed to respond with multiple 
www-authenticate values. Be it comma-separated or by sending the field multiple 
times.
This can be found in [1]  section 14.47 (something you experts are surely aware 
of .. *trying not to step on some ones toes* ;-) )
Further in [2] you can read, that a client should pick the most secure method 
it supports and start authentication then.

Well, not much of news till here.

Now my interpretation of the above: A client should pick the most secure 
authentication it is able to serve for the server and try this method. On 
failure, try the next method.
With this in mind, I setup an IIS site which allows Negotiate, NTLM, Digest and 
Basic and tried to open an java.net.URL against it.
To my surprise Digest will be chosen first (this is documented in 
sun.net.www.protocol.http.AuthenticationHeader, but wrong I think, shouldn't it 
be read like this:  negotiate -> kerberos -> ntlm -> digest -> basic) - also no 
other method will be tried yet.

Said that, I think the correct solution to this case will be to capture the 
already tried authentication methods until we don't know how to proceed.
Instead of passing "dontUseNegotiate" to the AuthenticationHeader, we will pass 
in a Set of already tried authentication methods.
This also should make it possible to avoid the use of inNegotiate. 
 
What do you think?
I think I am going to play a bit with this idea ... :-)

Ciao,
Mario

[1] http://www.ietf.org/rfc/rfc2616.txt
[2] http://msdn.microsoft.com/en-us/library/aa479391.aspx

-----Ursprüngliche Nachricht-----
Von: Weijun Wang [mailto:weijun.w...@oracle.com] 
Gesendet: Montag, 10. Oktober 2011 17:33
An: Chris Hegarty
Cc: Mario Ivankovits; net-dev@openjdk.java.net
Betreff: Re: ntlm with ms exchange server not working since java 1.7

During an NTLM handshake, I've never seen a server mentioning another scheme. 
As seen in message #4, the NTLM header still contains data, so there should not 
be WWW-Authenticate: Negotiate header.

That said, this is only my experience. I tried to find any words on this from 
an RFC but failed.

-Max



On Oct 10, 2011, at 7:48 AM, Chris Hegarty <chris.hega...@oracle.com> wrote:

> Max [to'ed],
> 
> Does this look familiar? Is it wrong for the server to be returning 
> "WWW-Authenticate: Negotiate" during NTLM handshake?
> 
> -Chris.
> 
> On 08/10/2011 14:41, Mario Ivankovits wrote:
>> Hi net-devs,
>> 
>> I hope you do not mind that I post to this list, but I hope I can 
>> provide enough in-depth information about the problem to justify the 
>> post here.
>> 
>> Accessing a “normal” ntlm protected resource – a simple index.html in 
>> an protected directory on an IIS 7.5 server - the ntlm authentication 
>> works fine.
>> 
>> However, trying to access the Microsoft Exchange 2010 webservice 
>> failes with “401 Unauthorized”.
>> 
>> I used this few lines to debug the connection/authentication process
>> 
>> URL url = new URL("https://exchange/ews/Services.wsdl";);
>> 
>> byte[] buf = new byte[10240];
>> 
>> int read = url.openStream().read(buf);
>> 
>> System.err.println(new String(buf, 0, read));
>> 
>> This snipped works fine in java 1.6, but failes with an IOException 
>> (http status 401) in java 1.7.
>> 
>> I found an interesting difference when accessing the “normal” 
>> web-page and the exchange webservice.
>> 
>> When accessing the web-page, the server answers “WWW-Authenticate:
>> Negotiate” just after the first 401 response which triggers the 
>> authentication process then. In contrast, when accessing the Exchange 
>> webservice the “WWW-Authenticate: Negotiate” is sent during the 
>> negotiation process too, which then triggers the inNegotiate flag in 
>> sun.net.www.protocol.http.HttpURLConnection in getInputStream and let 
>> the negotiation process fail.
>> 
>> If I hack the response values and change any subsequent Negotiate to 
>> e.g. NegotiateXX, then the inNegotiate flag will not change and the 
>> authentication process will finish and authentication finally works.
>> 
>> Here is the request/response cycle which fail then:
>> 
>> #1: {GET /ews/Services.wsdl HTTP/1.1: null}{User-Agent:
>> Java/1.7.0_02-ea}{Host: exchange }{Accept: text/html, image/gif, 
>> image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
>> 
>> #2: {null: HTTP/1.1 401 Unauthorized}{Server:
>> Microsoft-IIS/7.5}{WWW-Authenticate: Negotiate}{WWW-Authenticate:
>> NTLM}{X-Powered-By: ASP.NET}{Date: Sat, 08 Oct 2011 13:17:39
>> GMT}{Content-Length: 0}
>> 
>> #3: {GET /ews/Services.wsdl HTTP/1.1: null}{User-Agent:
>> Java/1.7.0_02-ea}{Host: exchange }{Accept: text/html, image/gif, 
>> image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}{Authorization:
>> NTLM MY_NTLM_DATA}
>> 
>> #4: {null: HTTP/1.1 401 Unauthorized}{Server:
>> Microsoft-IIS/7.5}{WWW-Authenticate: NTLM
>> SERVER_NTLM_DATA}{WWW-Authenticate: Negotiate}{X-Powered-By:
>> ASP.NET}{Date: Sat, 08 Oct 2011 13:17:39 GMT}{Content-Length: 0}
>> 
>> Exception in thread "main" java.io.IOException: Server returned HTTP 
>> response code: 401 for URL: https://exchange/ews/Services.wsdl
>> 
>> at
>> sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLCon
>> nection.java:1612)
>> 
>> at
>> sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Http
>> sURLConnectionImpl.java:254)
>> 
>> at java.net.URL.openStream(URL.java:1035)
>> 
>> Does this make sense to you?
>> 
>> It seems to me the “inNegotiate” handling needs a review as it does 
>> not work in all cases.
>> 
>> I hope my informations are of any help to fix this issue.
>> 
>> Ciao,
>> 
>> Mario
>> 

Reply via email to