JDK-6589477 : 2nd call to HTTP/SPNEGO fails when http.auth.preference=Negotiate is set
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6u17,7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-08-06
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6u21Fixed 7 b19Fixed
Related Reports
Duplicate :  
If more than two HTTP/SPNEGO protected URLs are requested, and -Dhttp.auth.preference=Negotiate is set, the second request may fail.

This is not of high priority because the system property http.auth.preference is normally used to choose a weaker authentication scheme when multiple schemes are supported by the server. Currently, Negotiate is the strongest scheme, therefore, user seldom specifies the property as "Negotiate".

EVALUATION No regression test, need KDC and web server setup.

EVALUATION The problem lies in NegotiateAuthenticatin.java: 199 private byte[] firstToken() throws IOException { 200 if (cache != null) { 201 synchronized(cache) { 202 negotiator = cache.get(getHost()); 203 if (negotiator != null) { 204 cache.remove(getHost()); // so that it is only used once 205 } 206 } 207 } 208 if (negotiator == null) { 209 try { 210 negotiator = Negotiator.getSupported(getHost(), scheme); Here, the code first tries to get the negotiator object from the cache, if not found, creates a fresh one using Negotiator.getSupported(). However, the negotiator object is not set to null before the "if (cache != null)" check. If the cache is null (which is the case when -Dhttp.auth.preference=Negotiate is set), and negotiator is not null before the method is called, a stale negotiator will be used and authentication will fail. To fix this problem, add "negotiator = null" at the beginning of this method. Background: In order to detect if Negotiate is supported by a given host, we first try to create an initial GSS token. If it's created successfully, the token is saved along with the GSS session context as a Negotiator object inside the cache. When the authentication process starts, the token is taken out and sent to the server. For security reasons, an initial token can be used *only once* so it must be removed from the cache (line 204) if it's about to be sent off. When user specifies the http.auth.preference property, there's no need to check if negotiate is supported since we don't need to support fallback. In this case, cache is never used and always null.