AW: ntlm with ms exchange server not working since java 1.7
Mario Ivankovits
mario at datenwort.at
Mon Oct 10 23:40:18 PDT 2011
Hi!
> That's "http.auth.preference" again, we now only accept one value for
> this property, so you can make it "NTLM" but not "NTLM,Digest".
>
> I can take a look at the patch, but honestly, I'm so afraid of touching
> the HttpURLConnection class and its siblings.
It is fully understandable, however, I hope time will come to polish up this class. ;-)
However, I've also found a drawback of my solution. Once a auth method has tried, I can not retry it in this cycle, means, if the user provided wrong credentials in an Swing-Authenticator he/she is not able to try it again as my patch prevents that. So, yes, first of all one needs to work out what and how the HttpURLConnection should behave in which situation. Probably we will see a java.nnet (like java.nio) package sometimes?
Ok, I'll concentrate back on my main issue because I am VERY sure others will catch that too.
The whole point of the inNegotiate stuff seems to be: If we used Negotiate or Kerberos and this did not work, avoid trying it again, but fallback to the next authentication scheme. (sounds familiar ;-) )
If this is the case, than the only thing missing is to check what the actual authentication scheme is.
So, adding an IF like this (++++) around the inNegotiate handling (3 times) did the trick too - much easier to review, right? ;-)
It mainly checks if we've already chosen an authentication scheme and then checks if we are still doing it. Basically this gives the dontUseNegotiate flag one additional cycle until it triggers.
Attached again the full source of the class.
boolean dontUseNegotiate = false;
++++ if (serverAuthentication != null && (AuthScheme.NEGOTIATE.equals(serverAuthentication.authScheme) || AuthScheme.KERBEROS.equals(serverAuthentication.authScheme))) {
Iterator iter = responses.multiValueIterator("WWW-Authenticate");
while (iter.hasNext()) {
String value = ((String)iter.next()).trim();
if (value.equalsIgnoreCase("Negotiate") ||
value.equalsIgnoreCase("Kerberos")) {
if (!inNegotiate) {
inNegotiate = true;
} else {
dontUseNegotiate = true;
doingNTLM2ndStage = false;
serverAuthentication = null;
}
break;
}
}
}
>>> A rather ugly hack is to choose NTLM as long as it has extra parameter(s). Hopefully that's safe. We know NTLM has defined 3 messages and that means the final answer from server is simply 200 OK without any 4th confirmation...
>> Yep, that will fix my main issue, but will not help in trying all the possible authentication methods announced by the server.
>Why not? If it's the first time NTLM is proposed as a scheme, it should not have any parameter. Therefore, I don't see a possibility that other schemes will be ignored.
It is not that the other schemes will be ignored. It is, that there is no defined fallback-strategy implemented in AuthenticationHeader. It just picks the first one it thinks is the best and sticks with it. One exception now is Negotiate and Kerberos which one tried to solve and make us the problems now.
Just thinking loud: What HttpURLConnection should do is:
1) If supported by the server (and the client platform, for sure) , try the authentication schemes which allow automatic, transparent login. This might be:
negotiate -> kerberos -> ntlm
2) If 1 failed and we have an Authenticator, read the credentials and try the most secure authentication scheme we are capable of
negotiate -> kerberos -> digest -> ntlm -> basic
Now I don't mind having the (probably more secure) DIGEST before NTLM as the transparent NTLM login has been tried already in 1.
Notice, now (because of 1) we can stick with the scheme we chose. No need to fallback from DIGEST to NTLM if authentication failed, as you said, if DIGEST fail something more fundamental might be wrong.
This preference here can be configured using the "http.auth.preference" property - as of today.
3) If 2 failed, go back to 2 - basically to ask the user again for the credentials (giving the user a chance to correct them).
Do the 3/2 loop until a max retry count has been reached or no credentials have been provided from the authenticator.
Sooner or later this rework needs to be done. But this are just my 2ct.
Ciao,
Mario
-------------- next part --------------
A non-text attachment was scrubbed...
Name: HttpURLConnection.java
Type: application/octet-stream
Size: 129946 bytes
Desc: HttpURLConnection.java
Url : http://mail.openjdk.java.net/pipermail/net-dev/attachments/20111011/47e7aa82/HttpURLConnection.java
More information about the net-dev
mailing list