■ 問題点に対するアプローチ
サーバに細工をし、「HTTPコード 407(プロキシ認証が必要)」を返せば ログアウト的なことをできるらしいができればJavaアプリだけで完結したい。 問題を発生した後に、再度、Basic認証が認証NGにテストをしたところ、 期待通り、NGになったので、チェック機能を別プロセスで実行すれば 実現できそうなので、以下の関連記事を応用して実装してみる。 # 他にもっといい方法あるといいんだが...Java から別のJava(JARファイル)を実行するには...
https://blogs.yahoo.co.jp/dk521123/37181644.html
■ 使用上の注意:Linux上での実行
* 以下のサンプルをWindows上(Windows7/10 Java1.8.0)で確認したところ問題なかったが Linux(Debian8/Java1.8.0_65)上では、値の受け渡しで桁あふれを起こしていた。 => 結論から言うと、System.exitに設定する値は『0~255』の範囲で行う必要がある 詳細は以下の関連記事を参照のこと。https://blogs.yahoo.co.jp/dk521123/37217908.html
例:HTTPコード 407 の時
【ProxySettingChecker.java】 System.exit(407); ↓ 【Main.java】(受け取り側) int result = process.waitFor(); // ★ result = 145 ★
■ サンプル
https://blogs.yahoo.co.jp/dk521123/36962466.htmlでプロキシ環境を構築する。以下の環境下を想定する。 * プロキシサーバ :192.168.211.123 * プロキシサーバポート:3128 * 認証ID :admin * 認証パスワード :passwordSSLについて
* 独自の証明書を設定している場合、事前に証明書をキーストアにインポートしておく必要がある ~[コマンド例]~~~ "%JAVA_HOME%\bin\keytool" -import -trustcacerts -alias java_proxy -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -storepass changeit -file cacert.pem ~~~~~~~~~~ => さもないと以下の例外が発生する ~~~~~~~~~~ sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target ~~~~~~~~~~https://blogs.yahoo.co.jp/dk521123/36518468.html
ProxySettingChecker.java
別プロセスとして実行したいJava。 ProxySettingChecker.jar にするimport java.io.IOException; import java.net.Authenticator; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.SocketTimeoutException; import java.net.URL; import javax.net.ssl.SSLHandshakeException; public class ProxySettingChecker { private static final int TIMEOUT = 5_000; /** * Mainメソッド. * @param args コマンドライン引数(詳細は以下の通り) * * <pre> * args[0] : 対象URL(http://xxxx) (Required) * args[1] : Proxy Host (Required) * args[2] : Proxy Port (Required) * args[3] : User Name (Optional) * args[4] : Password (Optional) * </pre> * * @throws Exception 引数不正 */ public static void main(String[] args) throws Exception { if (args == null || args.length < 3) { throw new IllegalArgumentException("Illegal Arguments"); } System.out.println("args.length : " + args.length); String targetUrl = args[0]; String proxyHost = args[1]; int proxyPort = Integer.valueOf(args[2]); if (args.length >= 5) { String userName = args[3]; String password = args[4]; if (userName != null && password != null) { System.out.println(userName + " " + password); // See https://qiita.com/kaakaa_hoe/items/d4fb11a3af035a287972 System.setProperty("jdk.http.auth.tunneling.disabledSchemes", ""); Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password.toCharArray()); } }); } } int responseCode = ProxySettingChecker.connectUsingProxy(proxyHost, proxyPort, targetUrl, TIMEOUT); if (ProxySettingChecker.isValidResponse(responseCode)) { System.out.println("OK Setting"); return; } System.err.println("NG Setting"); System.exit(responseCode); } private static int connectUsingProxy(String proxyHost, int proxyPort, String url, int timeout) { try { URL targetUrl = new URL(url); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection(proxy); connection.setConnectTimeout(timeout); connection.setReadTimeout(timeout); connection.setRequestMethod("HEAD"); return connection.getResponseCode(); } catch (SSLHandshakeException ex) { ex.printStackTrace(); return -4; } catch (SocketTimeoutException ex) { // ex.printStackTrace(); return -3; } catch (ConnectException ex) { // ex.printStackTrace(); return -2; } catch (IOException ex) { // ex.printStackTrace(); return -1; } } private static boolean isValidResponse(int responseCode) { return HttpURLConnection.HTTP_OK <= responseCode && responseCode <= 399; } }
Main.java
呼び出し側//import java.io.BufferedReader; //import java.io.InputStreamReader; public class Main { public static void main(String[] args) { System.out.println("Test1-1 : OK"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.123", "3128", "admin", "password"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Test1-2 : NG"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.123", "3128", "admin", "dummy"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Test1-3 : NG"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.123", "3128", "dummy", "password"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Test1-4 : NG"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.123", "3128"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Test2-1 : NG"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.1", "3128", "admin", "password"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Test2-2 : NG"); try { execute("java", "-jar", "ProxySettingChecker.jar", "http://www.msn.com/ja-jp", "192.168.211.123", "3129", "admin", "password"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } // SSLの場合、事前に証明書をキーストアにインポートしておく必要がある System.out.println("Test3-1 : OK"); try { execute("java", "-jar", "ProxySettingChecker.jar", "https://www.msn.com/ja-jp", "192.168.233.144", "3128", "admin", "password"); Thread.sleep(1000L); System.out.println(); } catch (Exception ex) { ex.printStackTrace(); } } private static void execute(String... commands) { ProcessBuilder processBuilder = new ProcessBuilder(commands); try { Process process = processBuilder.start(); int result = process.waitFor(); System.out.println("Result Code : " + result); if (result != 0) { System.err.println("Error!"); } // try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { // String line; // while ((line = bufferedReader.readLine()) != null) { // System.out.println(line); // } // } // try (BufferedReader errorBufferedreader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { // String errorLine; // while ((errorLine = errorBufferedreader.readLine()) != null) { // System.err.println(errorLine); // } // } } catch (Exception ex) { ex.printStackTrace(); } } }
出力結果
Test1-1 : OK Result Code : 0 Test1-2 : NG Result Code : 407 Error! Test1-3 : NG Error! Result Code : 407 Test1-4 : NG Error! Result Code : 407 Test2-1 : NG Error! Result Code : -3 Test2-2 : NG Result Code : -2 Error! Test3-1 : OK Result Code : 0