JDK-6947917 : Error in basic authentication when user name and password are long
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 5.0,6u15
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux,windows_xp
  • CPU: x86
  • Submitted: 2010-04-28
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
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.
JDK 7
7 b94Fixed
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.31-20-generic #58-Ubuntu SMP Fri Mar 12 04:38:19 UTC 2010 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When using java.net.Authenticator and java.net.PasswordAuthentication to set Basic Authentication credentials for a java.net.HttpURLConnection, you will get a error if the combined username and password are too long. This requires that the site being connected to is returning a rejection to facilitate Basic Authentication.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Set up a site that sends rejections similar to:

HttpServletResponse response;
response.setHeader("WWW-Authenticate", "Basic realm=\"Test\"");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

and then run this class:




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The client should get a rejection from the server to initiate basic authentication and then the client should send this as a header:

Basic UGFzc3dvcmRJc0F1dGhUb2tlbjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
ACTUAL -
The client gets the rejection to initiate basic authentication and then it generates a illegal HTTP header that line wraps but does not begin the next line with a space or tab.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic UGFzc3dvcmRJc0F1dGhUb2tlbjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:930)
	at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2031)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:376)
	at Main.main(Main.java:21)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;

public class Main {

    public static void main(String[] args)
    throws Exception {
        Authenticator.setDefault(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                Thread.dumpStack();
                return new PasswordAuthentication("PasswordIsAuthToken",
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".toCharArray());
            }
        });
        
        URL url = new URL("http://localhost:8080");
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        try {
            System.out.println("response code: " + urlConnection.getResponseCode());
        }
        finally {
            urlConnection.disconnect();
        }
    }

}

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

CUSTOMER SUBMITTED WORKAROUND :
Only known workaround is to use a 3rd party library for URL connections such as HttpClient.

Comments
EVALUATION JDK7 changeset: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/a6928350e1f2
07-05-2010

EVALUATION The Basic Authentication implementation, sun.net.www.protocol.http.BasicAuthentication, uses a sun.misc.BASE64Encoder to encode the Authentication headers field value. The sun.misc.BASE64Encoder class encodes 57 bytes per line. This results in a maximum of 57/3 * 4, or 76, characters per output line (not counting the line termination) before writing a LineSuffix, i.e. a newline character. With long long usernames and/or passwords it is possible to generate a header value with more than 76 characters, therefore causing a newline character to be returned as part of the header value. This violates the HTTP spec for Message Headers, which states that "Header fields can be extended over multiple lines by preceding each extra line with at least one SP or HT.". We should increase the number of bytes per line for the encoder used for Basic Authentication.
05-05-2010