United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6578647 Undefined requesting URL in "java.net.Authenticator.getPasswordAuthentication()"
6578647 : Undefined requesting URL in "java.net.Authenticator.getPasswordAuthentication()"

Details
Type:
Bug
Submit Date:
2007-07-10
Status:
Resolved
Updated Date:
2011-02-16
Project Name:
JDK
Resolved Date:
2009-06-22
Component:
core-libs
OS:
windows_xp
Sub-Component:
java.net
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
7

Related Reports
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
jdk1.6.0_01

A DESCRIPTION OF THE PROBLEM :
When I use "Negotiate"(Kerberos) authentication and I extend "java.net.Authenticator" class and redefine "getPasswordAuthentication()" method, I get NULL value from "getRequestingURL()" and "getRequestingHost()" method(these methods are defined in java.net.Authenticator class). When I use "Basic" authentication - all work properly(these methods return correct value).
I use HttpURLConnection class for both authentication schema.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package my.kerberos.test;

import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class is used as common point for standard java HttpURLConnection authentication.
 * It uses singleton pattern and do "Authenticator.setDefault(this)" in its constructor.
 * So it is default authenticator for all HttpURLConnection.
 *
 * @author Andrey Krasnov
 *
 */
public class BaseAuthenticator extends Authenticator {

	private Log log = LogFactory.getLog(this.getClass());
	
	private final static BaseAuthenticator instance = new BaseAuthenticator();
	static {
		Authenticator.setDefault(instance);
	}
	
	private Map<String, Account> urlMap = new HashMap<String, Account>();
	private Map<String, Account> hostMap = new HashMap<String, Account>();
	
	/**
	 * Register credentials for specified url
	 * @param url
	 * @param login
	 * @param password
	 * @return the previous value associated with key, or null if there was no mapping for key.
	 * (A null return can also indicate that the map previously associated null with key,
	 * if the implementation supports null values.)
	 */
	public static synchronized Account registerUrl(String url, String login, String password){
		if(url == null || login == null || password == null){
			throw new IllegalArgumentException("All parameters should be specified");
		}
		return instance.urlMap.put(url, new Account(login, password));
	}
	
	/**
	 * Register credentials for specified host
	 * @param host
	 * @param login
	 * @param password
	 * @return the previous value associated with key, or null if there was no mapping for key.
	 * (A null return can also indicate that the map previously associated null with key,
	 * if the implementation supports null values.)
	 */
	public static synchronized Account registerHost(String host, String login, String password){
		if(host == null || login == null || password == null){
			throw new IllegalArgumentException("All parameters should be specified");
		}
		return instance.hostMap.put(host, new Account(login, password));
	}
	
	/**
	 * Clear all registered credentials
	 */
	public static synchronized void reset(){
		instance.urlMap.clear();
		instance.hostMap.clear();
	}
	
	protected PasswordAuthentication getPasswordAuthentication() {
		
		log.debug("Authentication schema for \""+getRequestingURL()+"\": " + getRequestingScheme());
		
		Account account = urlMap.get(getRequestingURL());
		if( account != null ){
			return new PasswordAuthentication(account.login, account.password);
		}
		else if( (account = hostMap.get(getRequestingHost())) != null ){
			return new PasswordAuthentication(account.login, account.password);
		}
		
		return null;
	}
	
	/**
	 * This class encapsulates pair with login and password
	 *	@author Andrey Krasnov
	 *
	 */
	private static class Account {
		public final String login;
		public final char[] password;
		
		public Account(String login, String password){
			this.login = login;
			this.password = password.toCharArray();
		}
		
		public String toString(){
			return "[login: "+login+", password: ******]";
		}
	}
	
}

---------- END SOURCE ----------

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/tl/jdk/rev/8f405b65ddac
                                     
2009-06-09
EVALUATION

Fixed, various getXXX() methods now return useful info.
                                     
2009-06-09
EVALUATION

For Kerberos authentication, the username and password is for the realm and there's only one realm. Therefore, web server info such as host/port/URL are all ignored when retrieving authenticate info through the Authenticator class.
                                     
2007-07-31
EVALUATION

This violates the current Authenticator specification. The following methods are specified to possibly return null:

  getRequestingSite and getRequestingHost

but the following methods are not:

  getRequestingURL, getRequestorType, getRequestingScheme, getRequestingPrompt,
  getRequestingProtocol and getRequestingPort.

There seems to be a general specification issue with java.net.Authenticator. For example, if the authenticator was called by 
  requestPasswordAuthentication(InetAddress addr, int port, String protocol, String prompt, String scheme) 

   what will be returned from getRequestingURL and getRequestorType?
                                     
2007-07-31



Hardware and Software, Engineered to Work Together