web-dev-qa-db-ja.com

Javaで認証されたHTTPプロキシ

Javaを使用してhttpプロキシサーバーを認証するためにユーザー名とパスワードを構成するにはどうすればよいですか?

次の構成パラメーターを見つけました。

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

しかし、プロキシサーバーには認証が必要です。プロキシサーバーを使用するようにアプリを構成するにはどうすればよいですか?

56
Andre Pastore

(編集:OPが指摘したように、Java.net.Authenticatorも必要です。正確さのために、それに応じて回答を更新しています。)

認証には、Java.net.Authenticatorプロキシの構成を設定し、システムプロパティを設定しますhttp.proxyUserおよびhttp.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);
74
Pascal Thivent

あなたはほとんどそこにいるので、追加するだけです:

-Dhttp.proxyUser=someUserName
-Dhttp.proxyPassword=somePassword
32
OscarRyz

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;
    }  
});

まだ試していませんが、良さそうです。

このため、equals(Host.toLowerCase())の代わりにequalsIgnoreCase()を使用するように元のバージョンを少し変更しました。 http://mattryall.net/blog/2009/02/the-infamous-turkish-locale -bug およびInteger.parseInt(port)のNumberFormatExceptionを回避するために、ポートのデフォルト値として「80」を追加しました。

29
jcsahnwaldt

答えのほとんどは既存の返信にありますが、私にとってはそうではありません。これは、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:ユーザー認証を使用したプロキシ、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( "key"、 "value)でプロパティを設定することもできます。

HTTPSリソースにアクセスするには、サーバー証明書をダウンロードしてトラストストアに保存し、そのトラストストアを使用して、リソースを信頼する必要があります。すなわち

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

ただし、そのパラメーターのみを設定すると、認証は機能しません。

そのコードに次を追加する必要があります。

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());
    }
  }
);
10
Andre Pastore

Java 1.8以降では設定が必要です

-Djdk.http.auth.tunneling.disabledSchemes =

承認済みの回答に記載されているように、Authenticatorとともにhttpsで動作するBasic Authorizationのプロキシを作成する

8
Anton

私が書いたこのランナーを試してください。役に立つかもしれません。

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});
    }

}
4
MichealKum