mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8199849: Add support for UTF-8 encoded credentials in HTTP Basic Authentication
Reviewed-by: chegar, dfuchs
This commit is contained in:
parent
f2e17b7658
commit
e3b6b7f842
7 changed files with 623 additions and 71 deletions
|
@ -29,11 +29,17 @@ import java.net.URL;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import sun.net.www.HeaderParser;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.nio.charset.StandardCharsets.ISO_8859_1;
|
||||
|
||||
/**
|
||||
* BasicAuthentication: Encapsulate an http server authentication using
|
||||
|
@ -49,37 +55,18 @@ class BasicAuthentication extends AuthenticationInfo {
|
|||
|
||||
/** The authentication string for this host, port, and realm. This is
|
||||
a simple BASE64 encoding of "login:password". */
|
||||
String auth;
|
||||
final String auth;
|
||||
|
||||
/**
|
||||
* Create a BasicAuthentication
|
||||
*/
|
||||
public BasicAuthentication(boolean isProxy, String host, int port,
|
||||
String realm, PasswordAuthentication pw,
|
||||
String authenticatorKey) {
|
||||
boolean isUTF8, String authenticatorKey) {
|
||||
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
|
||||
AuthScheme.BASIC, host, port, realm,
|
||||
Objects.requireNonNull(authenticatorKey));
|
||||
String plain = pw.getUserName() + ":";
|
||||
byte[] nameBytes = null;
|
||||
try {
|
||||
nameBytes = plain.getBytes("ISO-8859-1");
|
||||
} catch (java.io.UnsupportedEncodingException uee) {
|
||||
assert false;
|
||||
}
|
||||
|
||||
// get password bytes
|
||||
char[] passwd = pw.getPassword();
|
||||
byte[] passwdBytes = new byte[passwd.length];
|
||||
for (int i=0; i<passwd.length; i++)
|
||||
passwdBytes[i] = (byte)passwd[i];
|
||||
|
||||
// concatenate user name and password bytes and encode them
|
||||
byte[] concat = new byte[nameBytes.length + passwdBytes.length];
|
||||
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
|
||||
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
|
||||
passwdBytes.length);
|
||||
this.auth = "Basic " + Base64.getEncoder().encodeToString(concat);
|
||||
this.auth = authValueFrom(pw, isUTF8);
|
||||
this.pw = pw;
|
||||
}
|
||||
|
||||
|
@ -99,34 +86,30 @@ class BasicAuthentication extends AuthenticationInfo {
|
|||
* Create a BasicAuthentication
|
||||
*/
|
||||
public BasicAuthentication(boolean isProxy, URL url, String realm,
|
||||
PasswordAuthentication pw,
|
||||
PasswordAuthentication pw, boolean isUTF8,
|
||||
String authenticatorKey) {
|
||||
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
|
||||
AuthScheme.BASIC, url, realm,
|
||||
Objects.requireNonNull(authenticatorKey));
|
||||
String plain = pw.getUserName() + ":";
|
||||
byte[] nameBytes = null;
|
||||
try {
|
||||
nameBytes = plain.getBytes("ISO-8859-1");
|
||||
} catch (java.io.UnsupportedEncodingException uee) {
|
||||
assert false;
|
||||
}
|
||||
|
||||
// get password bytes
|
||||
char[] passwd = pw.getPassword();
|
||||
byte[] passwdBytes = new byte[passwd.length];
|
||||
for (int i=0; i<passwd.length; i++)
|
||||
passwdBytes[i] = (byte)passwd[i];
|
||||
|
||||
// concatenate user name and password bytes and encode them
|
||||
byte[] concat = new byte[nameBytes.length + passwdBytes.length];
|
||||
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
|
||||
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
|
||||
passwdBytes.length);
|
||||
this.auth = "Basic " + Base64.getEncoder().encodeToString(concat);
|
||||
this.auth = authValueFrom(pw, isUTF8);
|
||||
this.pw = pw;
|
||||
}
|
||||
|
||||
private static String authValueFrom(PasswordAuthentication pw, boolean isUTF8) {
|
||||
String plain = pw.getUserName() + ":";
|
||||
char[] password = pw.getPassword();
|
||||
CharBuffer cbuf = CharBuffer.allocate(plain.length() + password.length);
|
||||
cbuf.put(plain).put(password).flip();
|
||||
Charset charset = isUTF8 ? UTF_8 : ISO_8859_1;
|
||||
ByteBuffer buf = charset.encode(cbuf);
|
||||
ByteBuffer enc = Base64.getEncoder().encode(buf);
|
||||
String ret = "Basic " + new String(enc.array(), enc.position(), enc.remaining(), ISO_8859_1);
|
||||
Arrays.fill(buf.array(), (byte) 0);
|
||||
Arrays.fill(enc.array(), (byte) 0);
|
||||
Arrays.fill(cbuf.array(), (char) 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BasicAuthentication
|
||||
*/
|
||||
|
|
|
@ -2265,6 +2265,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||
if (host != null && authhdr.isPresent()) {
|
||||
HeaderParser p = authhdr.headerParser();
|
||||
String realm = p.findValue("realm");
|
||||
String charset = p.findValue("charset");
|
||||
boolean isUTF8 = (charset != null && charset.equalsIgnoreCase("UTF-8"));
|
||||
String scheme = authhdr.scheme();
|
||||
AuthScheme authScheme = UNKNOWN;
|
||||
if ("basic".equalsIgnoreCase(scheme)) {
|
||||
|
@ -2310,7 +2312,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||
realm, scheme, url, RequestorType.PROXY);
|
||||
if (a != null) {
|
||||
ret = new BasicAuthentication(true, host, port, realm, a,
|
||||
getAuthenticatorKey());
|
||||
isUTF8, getAuthenticatorKey());
|
||||
}
|
||||
break;
|
||||
case DIGEST:
|
||||
|
@ -2428,6 +2430,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||
HeaderParser p = authhdr.headerParser();
|
||||
String realm = p.findValue("realm");
|
||||
String scheme = authhdr.scheme();
|
||||
String charset = p.findValue("charset");
|
||||
boolean isUTF8 = (charset != null && charset.equalsIgnoreCase("UTF-8"));
|
||||
AuthScheme authScheme = UNKNOWN;
|
||||
if ("basic".equalsIgnoreCase(scheme)) {
|
||||
authScheme = BASIC;
|
||||
|
@ -2479,7 +2483,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
|||
realm, scheme, url, RequestorType.SERVER);
|
||||
if (a != null) {
|
||||
ret = new BasicAuthentication(false, url, realm, a,
|
||||
getAuthenticatorKey());
|
||||
isUTF8, getAuthenticatorKey());
|
||||
}
|
||||
break;
|
||||
case DIGEST:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue