[9] RFR 8138953: HttpURLConnection doesn't fallback to another auth scheme if negotiate process failed
Artem Smotrakov
artem.smotrakov at oracle.com
Wed Oct 7 15:51:11 UTC 2015
Hi Max,
HttpURLConnection obtains credentials for HTTP authentication from
Authenticator [1] implementation. Only one authenticator can be set in
JVM instance. It can have built-in credentials, or do some interactions
with user to get them. Theoretically, it can provide different
credentials depending on a user/application/etc. I don't know how it is
used in real application, but it seems to be a possible situation. When
I was looking into this, I found a tech note [2] which says the
following about fallback
...
Fallback
If the server has provided more than one authentication schemes
(including Negotiate), according to the processing order mentioned in
the last section, Java will try to challenge the Negotiate scheme.
However, if the protocol cannot be established successfully (e.g. The
kerberos configuration is not correct, or the server's hostname is not
recorded in the KDC principal DB, or the username and password provided
by Authenticator is wrong), then the 2nd strongest scheme will be
automatically used. Attention : If http.auth.preference is set to SPNEGO
or Kerberos, then we assume you only want to try the Negotiate scheme
even if it fails. we won't fallback to any other scheme and your program
will result in throwing an IOException saying it receives a 401 or 407
error from the HTTP response.
...
As far as I understand, the current version of HttpURLConnection doesn't
seem to follow this. That's why I think it needs to be fixed. Otherwise,
the tech note [2] should be updated.
It doesn't look like a serious issue for me (that's why it is P3, or
maybe it should be P4). Furthermore, it looks like nobody has had such a
problem before because I didn't fine any bug about that at
https://bugs.openjdk.java.net
According to [2], Digest -> Basic fallback should not happen.
HttpURLConnection is quite smart, and if I understand correctly, we have
only "http.auth.preference" and Authenticator.setDefault() to control
HTTP authentication process. Maybe we can make it more configurable.
[1] http://docs.oracle.com/javase/8/docs/api/java/net/Authenticator.html
[2]
https://docs.oracle.com/javase/8/docs/technotes/guides/net/http-auth.html
Artem
On 10/07/2015 05:39 PM, Wang Weijun wrote:
> I will look into this. Busy on something else at the moment.
>
> Do you think this would happen in reality? There weren't a lot of fallback in HTTP auth, IMO, is that because in most cases username and password are the same for all schemes, and if one fails, we believe the pair is wrong and there is no need to try another. Negotiate was picked as a special case because configuration could go wrong even if the username and password are correct, and we provide a fallback.
>
> For example, what about fallback from Digest to Basic? Could the digest credentials be provided correctly at first and wrong later? What would happen?
>
> I haven't read the HttpURLConnection class for a long time and I could be wrong.
>
> Thanks
> Max
>
>> On Oct 7, 2015, at 7:19 PM, Artem Smotrakov <artem.smotrakov at oracle.com> wrote:
>>
>> Hello,
>>
>> Please review this for 9.
>>
>> According to [1], an HTTP client should try to use another HTTP authentication scheme if negotiate process failed for some reason, and a user didn't specify SPNEGO or Kerberos in "http.auth.preference" system property. But no fallback happens if, for example:
>> - an HTTP server supports both Negotiate (via Kerberos) and Basic authentication schemes
>> - first, a user provides correct Kerberos credentials, and a connection is successfully established with Negotiate scheme
>> - then, a user provides wrong Kerberos credentials, but correct Basic credentials
>>
>> This fix updates HttpURLConnection to try another authentication scheme negotiate process failed, and SPNEGO and Kerberos schemes are not preferred. The fix may be shorter, for example:
>>
>> if ( serverAuthentication != null || inNegotiate && !"negotiate".equals(AuthenticationHeader.authPref)) {
>>
>> , but I thought that some logging might be helpful.
>>
>> Also added a test which checks this and a couple of other scenarios work fine.
>>
>> Bug: https://bugs.openjdk.java.net/browse/JDK-8138953
>> Webrev: http://cr.openjdk.java.net/~asmotrak/8138953/webrev.00/
>>
>> [1] https://docs.oracle.com/javase/8/docs/technotes/guides/net/http-auth.html
>>
>> Artem
More information about the net-dev
mailing list