United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6589477 2nd call to HTTP/SPNEGO fails when http.auth.preference=Negotiate is set
JDK-6589477 : 2nd call to HTTP/SPNEGO fails when http.auth.preference=Negotiate is set

Details
Type:
Bug
Submit Date:
2007-08-06
Status:
Closed
Updated Date:
2011-05-18
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
core-libs
OS:
generic
Sub-Component:
java.net
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
6u17,7
Fixed Versions:

Related Reports
Backport:
Duplicate:

Sub Tasks

Description
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".

                                    

Comments
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.
                                     
2007-08-06
EVALUATION

No regression test, need KDC and web server setup.
                                     
2007-08-08



Hardware and Software, Engineered to Work Together