问题
I am faced with a curious behaviour of java6/8. I try to tunnel through a proxy which needs basic user authentication. Doing this by the standard java Authenticator. If I try to access a https url as the first url, an exception is thrown:
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"
But if I access a http URL first and then the https URL, the https access works fine.
Given that code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
public class ProxyPass {
public ProxyPass( String proxyHost, int proxyPort, final String userid, final String password, String url ) {
try {
/* Create a HttpURLConnection Object and set the properties */
URL u = new URL( url );
Proxy proxy = new Proxy( Proxy.Type.HTTP, new InetSocketAddress( proxyHost, proxyPort ) );
HttpURLConnection uc = (HttpURLConnection) u.openConnection( proxy );
Authenticator.setDefault( new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType().equals( RequestorType.PROXY )) {
return new PasswordAuthentication( userid, password.toCharArray() );
}
return super.getPasswordAuthentication();
}
} );
uc.connect();
/* Print the content of the url to the console. */
showContent( uc );
}
catch (IOException e) {
e.printStackTrace();
}
}
private void showContent( HttpURLConnection uc ) throws IOException {
InputStream i = uc.getInputStream();
char c;
InputStreamReader isr = new InputStreamReader( i );
BufferedReader br = new BufferedReader( isr );
String line;
while ((line = br.readLine()) != null) {
System.out.println( line );
}
}
public static void main( String[] args ) {
String proxyhost = "proxyHost";
int proxyport = proxyPort;
final String proxylogin = proxyUser;
final String proxypass = proxyPass;
String url = "http://www.google.de";
String surl = "https://www.google.de";
// new ProxyPass( proxyhost, proxyport, proxylogin, proxypass, url ); // uncomment this line to see that the https request works!
// System.out.println( url + " ...ok" ); // uncomment this line to see that the https request works!
new ProxyPass( proxyhost, proxyport, proxylogin, proxypass, surl );
System.out.println( surl + " ...ok" );
}
Any suggestions, ideas?
回答1:
You have to edit the variables
jdk.http.auth.tunneling.disabledSchemes and jdk.http.auth.proxying.disabledSchemes to blank like this:
jdk.http.auth.tunneling.disabledSchemes=
jdk.http.auth.proxying.disabledSchemes=
In my case I found in this file
jdk1.8.0_111/jre/lib/net.properties
回答2:
Change in Java 8 Update 111:
Now, proxies requiring Basic authentication when setting up a tunnel for HTTPS will no longer succeed by default. If required, this authentication scheme can be reactivated by removing Basic from the jdk.http.auth.tunneling.disabledSchemes networking property, or by setting a system property of the same name to "" ( empty ) on the command line.
http://www.oracle.com/technetwork/java/javase/8u111-relnotes-3124969.html
Your options:
- solve the issue (for the sake of security) by upgrading the authentication scheme of your proxy, e.g. to Digest access authentication
or just workaround the issue by running Java with
java -Djdk.http.auth.tunneling.disabledSchemes=""
来源:https://stackoverflow.com/questions/41505219/unable-to-tunnel-through-proxy-proxy-returns-http-1-1-407-via-https