Java プロキシのパスワードに含まれる @
生のパスワードを PasswordAuthentication に渡し、URL エンコードは実際のプロキシ URL を組み立てるときにだけ適用します。
java.net.PasswordAuthentication はユーザー名とパスワードの文字配列を受け取ります。パスワードの元の文字をそのまま渡します:
var credential = new java.net.PasswordAuthentication(
"proxy-user", "p@ssword".toCharArray());
この値は説明用のパスワードです。アプリケーションコードでは、想定された認証情報の取得元から実際の文字を取得してください。
このパスワード内の @ はデータです。パスワードにはすでに独自の引数があるためです。コンストラクタに渡す前に p%40ssword へ変換すると、別のパスワードを渡すことになります。
プロキシ URL には 別の認証情報の表現があります。http://proxy-user:p%[email protected]:8080 のような URL では、エンコードされた @ はユーザー情報の内部に属し、後ろの @ がその情報とホストを区切ります。値を実際に消費するインターフェースに合わせてデコードとエンコードを行ってください。
シェルのクォート、Java 文字列リテラルのエスケープ、URL のパーセントエンコードも、それぞれ異なる構文解析の問題を解決します。リクエストの挙動が変わるまで認証情報を繰り返しエンコードするのではなく、どの層が入力を読んでいるのかを特定してください。