2009-10-26 47 views
46

如何配置用戶名和密碼來驗證使用Java的http代理服務器?通過Java驗證的HTTP代理

我剛剛發現了以下配置參數:

http.proxyHost=<proxyAddress> 
http.proxyPort=<proxyPort> 
https.proxyHost=<proxyAddress> 
https.proxyPort=<proxyPort> 

但是,我的代理服務器需要認證。我如何配置我的應用程序以使用代理服務器?

+2

沒有代理服務器接受什麼樣的認證/要求?基礎,摘要或NTLM? – brianegge 2009-10-27 01:56:27

回答

65

(編輯:。正如OP指出,需要使用java.net.Authenticator過我相應地更新我的回答是否正確的緣故)

對於身份驗證,使用java.net.Authenticator設置代理服務器的配置和設置系統屬性http.proxyUserhttp.proxyPassword

final String authUser = "user"; 
final String authPassword = "password"; 
Authenticator.setDefault(
    new Authenticator() { 
     @Override 
     public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(
       authUser, authPassword.toCharArray()); 
     } 
    } 
); 

System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 
+2

我也得到了代碼片段的迴應。但是,當我爲密碼設置了錯誤的值時,如果請求通過代理,它應該說連接被拒絕。在那種情況下,我也得到了輸出。我如何驗證請求是否通過代理髮送? – divinedragon 2013-01-30 13:11:37

+0

@Pascal:我覺得你的意思是那些最後兩行設置'proxyHost'和'proxyPort',不'proxyUser'和'proxyPassword',因爲後者已經由Authenticator成立。或者我錯過了什麼? – 2013-08-26 12:40:05

+0

@divinedragon它不應該說'連接被拒絕'。這甚至不可能。連接被TCP接受,然後代理失敗了。在這一點上,代理不可能產生拒絕連接。 – EJP 2014-04-26 10:38:04

23

就快,你只需要追加:

-Dhttp.proxyUser=someUserName 
-Dhttp.proxyPassword=somePassword 
10

但是,設置只參數,認證不工作。

是必要的,添加到代碼如下:

final String authUser = "myuser"; 
final String authPassword = "secret"; 

System.setProperty("http.proxyHost", "hostAddress"); 
System.setProperty("http.proxyPort", "portNumber"); 
System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 

Authenticator.setDefault(
    new Authenticator() { 
    public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(authUser, authPassword.toCharArray()); 
    } 
    } 
); 
+0

您不必添加驗證器。對於我來說,使用Java 7和Java 8就足以設置http。*屬性。 – 2016-12-06 13:31:05

3

試試這個亞軍我寫的。這可能會有所幫助。

import java.io.InputStream; 
import java.lang.reflect.Method; 
import java.net.Authenticator; 
import java.net.PasswordAuthentication; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Scanner; 

public class ProxyAuthHelper { 

    public static void main(String[] args) throws Exception { 
     String tmp = System.getProperty("http.proxyUser", System.getProperty("https.proxyUser")); 
     if (tmp == null) { 
      System.out.println("Proxy username: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final String userName = tmp; 

     tmp = System.getProperty("http.proxyPassword", System.getProperty("https.proxyPassword")); 
     if (tmp == null) { 
      System.out.println("Proxy password: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final char[] password = tmp.toCharArray(); 

     Authenticator.setDefault(new Authenticator() { 
      @Override 
      protected PasswordAuthentication getPasswordAuthentication() { 
       System.out.println("\n--------------\nProxy auth: " + userName); 
       return new PasswordAuthentication (userName, password); 
      } 

     }); 

     Class<?> clazz = Class.forName(args[0]); 
     Method method = clazz.getMethod("main", String[].class); 
     String[] newArgs = new String[args.length - 1]; 
     System.arraycopy(args, 1, newArgs, 0, newArgs.length); 
     method.invoke(null, new Object[]{newArgs}); 
    } 

} 
26

http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword說:

其他建議使用自定義的默認身份驗證。但這很危險,因爲這會將你的密碼發送給任何詢問的人。

如果某些http/https請求沒有通過代理(這很可能取決於配置),這是相關的。在這種情況下,您可以將您的憑證直接發送到某個http服務器,而不是您的代理服務器。

他建議以下修復。

// Java ignores http.proxyUser. Here come's the workaround. 
Authenticator.setDefault(new Authenticator() { 
    @Override 
    protected PasswordAuthentication getPasswordAuthentication() { 
     if (getRequestorType() == RequestorType.PROXY) { 
      String prot = getRequestingProtocol().toLowerCase(); 
      String host = System.getProperty(prot + ".proxyHost", ""); 
      String port = System.getProperty(prot + ".proxyPort", "80"); 
      String user = System.getProperty(prot + ".proxyUser", ""); 
      String password = System.getProperty(prot + ".proxyPassword", ""); 

      if (getRequestingHost().equalsIgnoreCase(host)) { 
       if (Integer.parseInt(port) == getRequestingPort()) { 
        // Seems to be OK. 
        return new PasswordAuthentication(user, password.toCharArray()); 
       } 
      } 
     } 
     return null; 
    } 
}); 

我還沒試過,但對我來說看起來不錯。

我修改了原來的版本略有使用equalsIgnoreCase()而不是等號(host.toLowerCase()),因爲這樣:http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug和我說「80」作爲端口的默認值,以避免在NumberFormatException的的Integer.parseInt(港口)。

7

大部分的答案都在那裏,但對我來說並不完全。這對我來說適用於java.net.HttpURLConnection(我用JDK 7和JDK 8測試了所有的情況)。請注意,您不必使用Authenticator類。

情況1:代理,而無需用戶驗證,訪問HTTP資源

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport 

情況2:代理與用戶驗證,訪問HTTP資源

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

情況3:代理,而無需用戶認證,訪問HTTPS資源(SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

案例4:代理用戶au的用戶鑑定,訪問HTTPS資源(SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

案例5:代理,而無需用戶驗證,訪問HTTP和HTTPS資源(SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

案例6:代理與用戶的認證,訪問兩個HTTP和HTTPS資源(SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttp.proxyUser=myuser -Dhttp.proxyPassword=mypass -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

你可以用System.setProperty( 「鍵」,「值)也設置在了性能。

要訪問HTTPS資源,你可能必須通過下載服務器證書並將其保存在一個信任存儲,然後使用該信任存儲信任資源。即

System.setProperty("javax.net.ssl.trustStore", "c:/temp/cert-factory/my-cacerts"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
+1

我可以證實,使用身份驗證類,則無須對JDK 7或8只需使用'-D .proxyUser ='和'-D .proxyPassword ='。 – 2017-03-29 16:56:04

+0

感謝編輯@Cristiano – 2017-06-08 09:40:33

1

對於Java 1.8和更高您必須設置

-Djdk.http.auth.tunneling.disabledSchemes =

使代理與基本授權以https正在與沿認證爲接受的回答中提到