java - Proxy password containing `@` in JVM -
i have scala code has managed negotiate (ntlm) proxy , access internet, specifying username , password so:
// based upon http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword authenticator.setdefault(new authenticator() { override protected def getpasswordauthentication: passwordauthentication = { if (getrequestortype eq requestortype.proxy) { val prot = getrequestingprotocol.tolowercase // allows return passwordauthentication when have // 4 of host, port, user , password _and_ host , // port match actual proxy wanting authentication. { host <- option(system.getproperty(prot + ".proxyhost")) if getrequestinghost.equalsignorecase(host) port <- try(augmentstring(system.getproperty(prot + ".proxyport")).toint).tooption if port == getrequestingport user <- option(system.getproperty(prot + ".proxyuser")) pass <- option(system.getproperty(prot + ".proxypassword")) } yield return new passwordauthentication(user, pass.tochararray) } // 1 of if-statements failed. no authentication you! null } })
however, i've been given new system username/password combination use, , password contains @
in it. i've tried using password directly, escaping (with both \
, \\
in case double-level of escaping needed), url-encoding (i.e. replacing @
%40
) , html-encoding (@
, @
) no avail.
i know password works, it's used on other systems non-jvm applications access internet setting http_proxy
variable, doesn't work here.
any ideas?
edit
to try , clear things up, i've tried simplifying code this:
authenticator.setdefault(new authenticator() { def urlencode(str: string): string = { val res = urlencoder.encode(str, "utf-8") // confirm it's working println(s"${str} -> ${res}") res } override protected def getpasswordauthentication: passwordauthentication = { if (getrequestortype eq requestortype.proxy) { return new passwordauthentication(urlencode("username"), urlencode("p@ssword").tochararray); } null } })
the environment being run in in spark cluster (run spark-submit
) on linux box. proxy corporate ntlm one.
if use known username , password combination doesn't contain @
works. if change 1 containing @
fails.
i've tried making val res = str
inside urlencode
function (in case doesn't need url encoded), tried having \\@
(with , without url encoding) , ^@
(with , without url encoding). every single time exception of unable tunnel through proxy. proxy returns "http/1.1 407 proxy authorization required"
.
i know username , password valid set in https_proxy
variable used curl, etc.
so unless fact proxy being set within running spark server somehow affects happens it, appears me jvm libraries not support having @
in authenticator proxies (at least).
the problem not within java.net
library code (edit: http basic proxies, have not yet been able test ntlm proxies). java.net
code can connect fine using passwords "@" in them. have put demo code below allows verify claim.
you not need escape string value pass java.net.passwordauthentication
, should pass password in plaintext there. java.net
library code take care of encoding password necessary when sending on network proxy (see demo code below verify claim).
i believe problem must in way configuring system outside of code have included in question far.
for example, have passed proxy hostname jvm or nearby system in such way confused "@" symbol?
please can provide more context?
demo code verify java.net library code can cope "@" in password
this code includes instructions on setting fiddler2 http proxy on local machine, configuring fiddler2 require password, , connecting through proxy using java.net library classes.
the code runs me as-is, , fails if change "password" variable incorrect password.
import java.io.bufferedreader; import java.io.inputstream; import java.io.inputstreamreader; import java.net.authenticator; import java.net.passwordauthentication; import java.net.url; import java.util.base64; public class q45749081 { public static void main(string[] args) throws exception { // start fiddler http proxy https://www.telerik.com/download/fiddler // click "rules" -> "require proxy authentication" // type "quickexec" box below fiddler's web sessions list: // prefs set fiddler.proxy.creds dxnlcm5hbwu6cebzc3dvcmq= // // sets fiddler require auth "username", "p@ssword" // // see https://stackoverflow.com/questions/18259969/changing-username-and-password-of-fiddler-proxy-server // note must start new process each time change password // here, sun.net.www.protocol.http.httpurlconnection caches proxy password // lifetime of jvm process string password = "p@ssword"; system.out.println( "prefs set fiddler.proxy.creds " + base64.getencoder().encodetostring("username:p@ssword".getbytes())); authenticator.setdefault(new authenticator() { @override protected passwordauthentication getpasswordauthentication() { return new passwordauthentication( "username", password.tochararray()); } }); system.setproperty("http.proxyhost", "localhost"); system.setproperty("http.proxyport", "8888"); system.out.println("connecting google via authenticated proxy password '" + password + "'"); try (inputstream conn = new url("http://www.google.com/").openstream()) { try (bufferedreader r = new bufferedreader(new inputstreamreader(conn))) { system.out.println(r.readline()); system.out.println("ok"); } } catch (exception e) { system.out.println("failed: " + e); } } }
first answer:
the code have shown taking password jvm system property. how putting password property? suspect problem lies there, rather in code have shown.
if on windows, , if setting password command-line argument, need use dos escape char "^", i.e.
java -dhttp.proxypassword=foo^@bar -jar myapp.jar
if use mechanism provide password java, may need different escaping scheme.
Comments
Post a Comment