java - Tomcat 6 - Java 代理隧道在 Windows 上失败 - 错误 - 407

标签 java tomcat proxy proxy.pac

我创建了一个类来处理 HTTP 代理以连接远程服务器以获取 Web 服务。部署在Tomcat 6上,在Windows server 2008上,在servlet中调用。

  1. 它与 $CATALINA_HOME\bin\tomcat6.exe 完美配合,即在 cmd 上。
  2. 它无法通过 Windows 服务实用程序的代理,即 $CATALINA_HOME\bin\tomcat6w.exe。

两者都读取相同的配置,但在通过代理与远程服务器建立连接时表现不同。

我找到了几种获取代理设置的方法,如下:

  1. 代理 Vole 实用程序 jar (proxy-vole_20131209.jar)。
  2. java.net.useSystemProxies 设置为 true 并获取代理信息。
  3. 使用 Java 代码 (deploy.jar) 阅读 PAC。
  4. 传递常量主机名/IP 和端口。

以上所有与 $CATALINA_HOME\bin\tomcat6.exe 一起工作,除了 PAC 读取,因为它获取私有(private) IP 或公共(public) IP(只要我知道确切的主机名和端口,现在可以忽略)。 注意:我没有找到代理凭据,并且在没有它的情况下也可以从 cmd 运行。 但是当我尝试使用 tomcat Windows 服务实用程序运行它时,即 $CATALINA_HOME\bin\tomcat6w.exe 它无法连接远程服务器并抛出异常: java.io.IOException:无法通过代理建立隧道。代理返回“HTTP/1.1 407 需要代理身份验证”

请找到我的类(class),它会逐一重试上述所有情况(跳过 PAC 一个)。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import com.btr.proxy.search.ProxySearch;
import com.btr.proxy.search.ProxySearch.Strategy;
import com.btr.proxy.util.PlatformUtil;
import com.btr.proxy.util.PlatformUtil.Platform;
import com.sun.deploy.net.proxy.BrowserProxyInfo;
import com.sun.deploy.net.proxy.DummyAutoProxyHandler;
import com.sun.deploy.net.proxy.ProxyConfigException;
import com.sun.deploy.net.proxy.ProxyInfo;
import com.sun.deploy.net.proxy.ProxyType;

public class ProxyPacManager {
public static void main(String args[]) throws Exception{
    getProxy();
}

public static Proxy getProxy(){
    String almProtocol = Constants.getPropereties().getProperty("dashboard.alm.protocol");
    String almHost = Constants.getPropereties().getProperty("dashboard.alm.host");
    String almPort = Constants.getPropereties().getProperty("dashboard.alm.port");
    String urlStr = almProtocol+almHost+":"+almPort;
    Proxy proxy = null;
    List<Proxy> proxyList = null;
    String successMsg = "Proxy not found.";
    try{
        System.out.println("Trying to connect through Proxy Vole plugin.");
        proxyList = getSSLCertificateAutoProxy(urlStr);
        proxy = getProxyTested(proxyList, urlStr);
        successMsg="Successfully connected through Proxy Vole plugin.";
    } catch(Exception ex){
        System.out.println("Proxy Vole plugin didn't work."+ex.getMessage());
        try{
            System.out.println("Trying to connect through java.net.useSystemProxies Proxy.");
            proxyList = getSSLCertificateSysProxy(urlStr);
            proxy = getProxyTested(proxyList, urlStr);
            successMsg="Successfully connected through java.net.useSystemProxies Proxy.";
        } catch(Exception ex1){
            System.out.println("java.net.useSystemProxies didn't work."+ex1.getMessage());
            try{
                /*System.out.println("Trying to connect through PAC Proxy.");
                proxyList = getSSLCertificatePACProxy(urlStr);
                proxy = getProxyTested(proxyList, urlStr);
                successMsg="Successfully connected through PAC Proxy.";*/
                throw new Exception("Bypass PAC Proxy for testing.");
            }catch(Exception ex2){
                System.out.println("PAC Proxy read didn't work."+ex2.getMessage());
                try{
                    System.out.println("Trying to connect through Constant Proxy.");
                    proxyList = getSSLCertificateConstantProxy();
                    proxy = getProxyTested(proxyList, urlStr);
                    successMsg="Successfully connected through Constant Proxy.";
                }catch(Exception ex3){
                    System.out.println("Constant Proxy read didn't work."+ex3.getMessage());
                    proxyList = new ArrayList<Proxy>();
                    proxyList.add(Proxy.NO_PROXY);
                    proxy = getProxyTested(proxyList, urlStr);
                    successMsg = "Connected with NO_PROXY";
                }
            }
        }
    }
    System.out.println(successMsg);
    return proxy;
}

private static Proxy getProxyTested(List<Proxy> proxyList, String urlStr){
    if (proxyList != null && !proxyList.isEmpty()) { 
         for (Proxy proxy : proxyList) { 
             SocketAddress address = proxy.address(); 
             if (address instanceof InetSocketAddress) {
                 System.out.println("Trying to connect through proxy: "+((InetSocketAddress) address).getHostName()+":"+((InetSocketAddress) address).getPort());
                try {
                    URLConnection connection = new URL(urlStr).openConnection(proxy);
                    connection.connect();               
                    System.out.println("Connected through proxy: "+((InetSocketAddress) address).getHostName()+":"+((InetSocketAddress) address).getPort());
                    return proxy; 
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }                                  
             } 
         } 
    }
    return null;
}

private static List<Proxy> getSSLCertificateConstantProxy() throws Exception{
    setCertificate();
    List<Proxy> proxyList = new ArrayList<Proxy>();
    String proxyHost = Constants.getPropereties().getProperty("dashboard.alm.proxy.host");
    InetAddress hostIp = InetAddress.getByName(proxyHost);
    int proxyPort = Integer.parseInt(Constants.getPropereties().getProperty("dashboard.alm.proxy.port"));

    //Create your proxy and setup authentication for it.
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(hostIp.getHostAddress(), proxyPort));                        
    //Setup authentication for your proxy.
    /*Authenticator.setDefault(new Authenticator() {

          @Override
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("<user>", "<password>".toCharArray());
          }
    });*/

    proxyList.add(proxy);
    return proxyList; 
}

private static void setCertificate() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException{
    //First, load the key store file
    String jksFile = Constants.getPropereties().getProperty("dashboard.alm.certificate");
    InputStream trustStream = new FileInputStream(jksFile); 
    String jksPass = Constants.getPropereties().getProperty("dashboard.alm.certificate.pass");
    char[] trustPassword = jksPass.toCharArray();

    //Initialize a KeyStore
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(trustStream, trustPassword);

    //Initialize TrustManager objects.
    TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustFactory.init(trustStore);
    TrustManager[] trustManagers = trustFactory.getTrustManagers();

    //Create a new SSLContext, load the TrustManager objects into it and set it as default.
    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, trustManagers, null);
    SSLContext.setDefault(sslContext);  
}
private static ProxyInfo[] getProxyInfo(String urlStr) throws ProxyConfigException, MalformedURLException{      
    String proxypac = Constants.getPropereties().getProperty("dashboard.alm.proxy.pac");        
    BrowserProxyInfo b = new BrowserProxyInfo();
    /*WDefaultBrowserProxyConfig wd = new WDefaultBrowserProxyConfig();
    BrowserProxyInfo b = wd.getBrowserProxyInfo();        */
    b.setType(ProxyType.AUTO);
    b.setAutoConfigURL(proxypac);       
    DummyAutoProxyHandler handler = new DummyAutoProxyHandler();
    handler.init(b);

    URL url = new URL(urlStr);
    ProxyInfo[] ps = handler.getProxyInfo(url);     

    return ps;
}

public static List<Proxy> getSSLCertificateAutoProxy(String urlStr) throws Exception{           
    setCertificate();
    /*ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();*/
    ProxySearch proxySearch = new ProxySearch();
    proxySearch.setPacCacheSettings(32, 1000*60*5);
    if (PlatformUtil.getCurrentPlattform() == Platform.WIN) { 
        proxySearch.addStrategy(Strategy.IE); 
        proxySearch.addStrategy(Strategy.FIREFOX); 
        proxySearch.addStrategy(Strategy.JAVA); 
    } else if (PlatformUtil.getCurrentPlattform() == Platform.LINUX) { 
        proxySearch.addStrategy(Strategy.GNOME); 
        proxySearch.addStrategy(Strategy.KDE); 
        proxySearch.addStrategy(Strategy.FIREFOX); 
    } else { 
        proxySearch.addStrategy(Strategy.OS_DEFAULT); 
    }       


    ProxySelector proxySelector = proxySearch.getProxySelector();
    /*BufferedProxySelector cachedSelector = new BufferedProxySelector(32, 1000*60*5, proxySelector);*/


    ProxySelector.setDefault(proxySelector); 
    //ProxySelector.setDefault(cachedSelector);
    URI home = URI.create(urlStr);  
    //List<Proxy> proxyList = cachedSelector.select(home); 
    List<Proxy> proxyList = proxySelector.select(home);
    return proxyList;
}

public static List<Proxy> getSSLCertificatePACProxy(String urlStr) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, ProxyConfigException{
    List<Proxy> proxyList = new ArrayList<Proxy>();
    setCertificate();       
    ProxyInfo[] ps = getProxyInfo(urlStr);      
    for(ProxyInfo p: ps){

        String proxyHost = p.getProxy();
        int proxyPort = p.getPort(); 

        //Create your proxy and setup authentication for it.
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));                      
        //Setup authentication for your proxy.
        /*Authenticator.setDefault(new Authenticator() {

              @Override
              protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("<user>", "<password>".toCharArray());
              }
        });*/
        proxyList.add(proxy);

    }
    return proxyList;

}


public static List<Proxy> getSSLCertificateSysProxy(String urlStr) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, ProxyConfigException, URISyntaxException{
    setCertificate();       
    System.setProperty("java.net.useSystemProxies","true");
    List<Proxy> proxyList = ProxySelector.getDefault().select(new URI(urlStr));

    return proxyList;

}

}

类的失败输出,

Trying to connect through java.net.useSystemProxies Proxy.
java.net.useSystemProxies didn't work.null
PAC Proxy read didn't work.Bypass PAC Proxy for testing.
Trying to connect through Constant Proxy.
Trying to connect through proxy: XX.XX.XXX.XX:8080 [Masked for security reasons]
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"

请帮助我使用 Tomcat 6 windows 服务实用程序通过代理。 注意:Windows 安全策略: 网络安全:LAN Manager 身份验证级别 = 仅发送 NTLM 响应

最佳答案

如果有人对此问题有任何解决方案,请尽快告诉我。 我将打破代码以获得更多理解:

  1. 通过Proxy vole plugin/jar获取代理

     public static List<Proxy> getSSLCertificateAutoProxy(String urlStr) throws Exception{          
    setCertificate();
    /*ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();*/
    ProxySearch proxySearch = new ProxySearch();
    proxySearch.setPacCacheSettings(32, 1000*60*5);
    if (PlatformUtil.getCurrentPlattform() == Platform.WIN) { 
        proxySearch.addStrategy(Strategy.IE); 
        proxySearch.addStrategy(Strategy.FIREFOX); 
        proxySearch.addStrategy(Strategy.JAVA); 
    } else if (PlatformUtil.getCurrentPlattform() == Platform.LINUX) { 
        proxySearch.addStrategy(Strategy.GNOME); 
        proxySearch.addStrategy(Strategy.KDE); 
        proxySearch.addStrategy(Strategy.FIREFOX); 
    } else { 
        proxySearch.addStrategy(Strategy.OS_DEFAULT); 
    }       
    
    
    ProxySelector proxySelector = proxySearch.getProxySelector();
    /*BufferedProxySelector cachedSelector = new BufferedProxySelector(32, 1000*60*5, proxySelector);*/
    
    
    ProxySelector.setDefault(proxySelector); 
    //ProxySelector.setDefault(cachedSelector);
    URI home = URI.create(urlStr);  
    //List<Proxy> proxyList = cachedSelector.select(home); 
    List<Proxy> proxyList = proxySelector.select(home);
    return proxyList;
    }
    
  2. 使用 java.net.useSystemProxies 获取代理

    public static List<Proxy> getSSLCertificateSysProxy(String urlStr) throws Exception{
     setCertificate();      
     System.setProperty("java.net.useSystemProxies","true");
     List<Proxy> proxyList = ProxySelector.getDefault().select(new URI(urlStr));
    
     return proxyList;
    
    }
    
  3. 从 PAC 获取代理:

    public static List<Proxy> getSSLCertificatePACProxy(String urlStr) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, ProxyConfigException{
    setCertificate();       
    List<Proxy> proxyList = new ArrayList<Proxy>();
    String proxypac = "<http://mydomain/proxy.pac>";        
    BrowserProxyInfo b = new BrowserProxyInfo();
    /*WDefaultBrowserProxyConfig wd = new WDefaultBrowserProxyConfig();
    BrowserProxyInfo b = wd.getBrowserProxyInfo();        */
    b.setType(ProxyType.AUTO);
    b.setAutoConfigURL(proxypac);       
    DummyAutoProxyHandler handler = new DummyAutoProxyHandler();
    handler.init(b);
    
    URL url = new URL(urlStr);
    ProxyInfo[] ps = handler.getProxyInfo(url); 
    for(ProxyInfo p: ps){
    
        String proxyHost = p.getProxy();
        int proxyPort = p.getPort(); 
    
        //Create your proxy and setup authentication for it.
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));                      
        //Setup authentication for your proxy.
        /*Authenticator.setDefault(new Authenticator() {
    
              @Override
              protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("<user>", "<password>".toCharArray());
              }
        });*/
        proxyList.add(proxy);
    
    }
    return proxyList;
    
    }
    
  4. 直接传递已知的代理主机名和端口获取代理

    private static List<Proxy> getSSLCertificateConstantProxy() throws Exception{
    
     setCertificate();
     List<Proxy> proxyList = new ArrayList<Proxy>();
     String proxyHost = "<myproxy.hostname>";
     InetAddress hostIp = InetAddress.getByName(proxyHost);
     int proxyPort = Integer.parseInt("<myProxyPort>"));
    
     //Create your proxy and setup authentication for it.
     Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(hostIp.getHostAddress(), proxyPort));                       
     //Setup authentication for your proxy.
     /*Authenticator.setDefault(new Authenticator() {
    
          @Override
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("<user>", "<password>".toCharArray());
          }
     });*/
    
     proxyList.add(proxy);
     return proxyList; 
    }
    

关于java - Tomcat 6 - Java 代理隧道在 Windows 上失败 - 错误 - 407,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37758920/

相关文章:

google-chrome - 谷歌浏览器中的 "Proxy server connection failed"

c - 转发代理检测FIN包

java - 如何(base64)将 protobuf 编码为字符串

java - 将支持 vector 机与 Encog 3 和多输出一起使用

java - 从依赖关系中排除单个 .java 文件?

Java Restful Service eclipse tomcat HTTP错误404

java - 针对不同tomcat war应用的多个logback.xml配置文件

Java:检测给定字符编码的不可显示字符

spring - 如何为 tomcat 6 及其部署的 webapps 正确配置 JNDI?

json - 我如何使用 json.Decoder 解码单个 json 消息并将连接切换到不同的协议(protocol)?