JustProxies

Examples

Selenium (Python · Java)

5-min readselenium
Selenium hands connections to the browser, not your code, so proxy auth needs a different approach than command-line tools. Chrome requires a small extension; Firefox accepts credentials natively.

Chrome — extension approach

Chrome ignores credentials embedded in --proxy-server. The reliable workaround is a tiny packed extension that calls chrome.proxy and handles the auth challenge. Build it in memory at runtime so there is nothing to ship:

selenium_chrome.pypython
import base64, io, zipfile
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

PROXY_HOST = "gw.justproxies.online"
PROXY_PORT = 8080
PROXY_USER = "USER"
PROXY_PASS = "PASS"

_manifest = """{
  "version": "1.0.0",
  "manifest_version": 2,
  "name": "Proxy Auth",
  "permissions": ["proxy", "webRequest", "webRequestBlocking", "<all_urls>"],
  "background": {"scripts": ["bg.js"]}
}"""

_background = f"""
chrome.proxy.settings.set({{
  value: {{
    mode: "fixed_servers",
    rules: {{
      singleProxy: {{ scheme: "http", host: "{PROXY_HOST}", port: {PROXY_PORT} }},
      bypassList: []
    }}
  }},
  scope: "regular"
}}, () => {{}});

chrome.webRequest.onAuthRequired.addListener(
  (details, callback) => callback({{
    authCredentials: {{ username: "{PROXY_USER}", password: "{PROXY_PASS}" }}
  }}),
  {{ urls: ["<all_urls>"] }},
  ["blocking"]
);
"""

def build_proxy_extension(host, port, user, pw):
    manifest = _manifest
    background = f"""
chrome.proxy.settings.set({{
  value: {{
    mode: "fixed_servers",
    rules: {{
      singleProxy: {{ scheme: "http", host: "{host}", port: {port} }},
      bypassList: []
    }}
  }},
  scope: "regular"
}}, () => {{}});
chrome.webRequest.onAuthRequired.addListener(
  (details, callback) => callback({{
    authCredentials: {{ username: "{user}", password: "{pw}" }}
  }}),
  {{ urls: ["<all_urls>"] }},
  ["blocking"]
);
"""
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, "w") as zf:
        zf.writestr("manifest.json", manifest)
        zf.writestr("bg.js", background)
    return base64.b64encode(buf.getvalue()).decode()

options = Options()
options.add_encoded_extension(
    build_proxy_extension(PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS)
)

driver = webdriver.Chrome(options=options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()
The extension uses Manifest V2 because Chrome's webRequest blocking API (required for auth) is not available in MV3. Pack it fresh per session rather than loading from disk so credentials never persist.

Firefox — Python

Firefox accepts proxy settings and port numbers natively via preferences. For auth, Firefox pops a credential dialog once per session — suppress it by pre-seeding the password manager or use the extension technique above. The simpler path for automation is to whitelist your server IP (contact support) so no auth challenge fires at all.

selenium_firefox.pypython
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

options = Options()
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.http",       "gw.justproxies.online")
options.set_preference("network.proxy.http_port",   8080)
options.set_preference("network.proxy.ssl",        "gw.justproxies.online")
options.set_preference("network.proxy.ssl_port",    8080)
options.set_preference("network.proxy.no_proxies_on", "")
# Avoid the credential dialog by whitelisting your egress IP with support,
# or provide pre-seeded credentials via the signon database.

driver = webdriver.Firefox(options=options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()

Java + ChromeDriver

Same extension trick, adapted for Java. Construct the zip in memory and pass it as a Base64 string via ChromeOptions.addExtensions(File) — or use the encoded form.

SeleniumProxy.javatext
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.Base64;
import java.util.zip.*;
import java.io.*;

public class SeleniumProxy {
    static final String HOST = "gw.justproxies.online";
    static final int    PORT = 8080;
    static final String USER = "USER";
    static final String PASS = "PASS";

    static String buildExtension() throws Exception {
        String manifest = """
            {"version":"1.0.0","manifest_version":2,"name":"PA",
             "permissions":["proxy","webRequest","webRequestBlocking","<all_urls>"],
             "background":{"scripts":["bg.js"]}}""";
        String bg = String.format("""
            chrome.proxy.settings.set({value:{mode:"fixed_servers",
              rules:{singleProxy:{scheme:"http",host:"%s",port:%d}}},
              scope:"regular"},()=>{});
            chrome.webRequest.onAuthRequired.addListener(
              (d,cb)=>cb({authCredentials:{username:"%s",password:"%s"}}),
              {urls:["<all_urls>"]},["blocking"]);
            """, HOST, PORT, USER, PASS);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        try (ZipOutputStream zip = new ZipOutputStream(buf)) {
            zip.putNextEntry(new ZipEntry("manifest.json"));
            zip.write(manifest.getBytes()); zip.closeEntry();
            zip.putNextEntry(new ZipEntry("bg.js"));
            zip.write(bg.getBytes()); zip.closeEntry();
        }
        return Base64.getEncoder().encodeToString(buf.toByteArray());
    }

    public static void main(String[] args) throws Exception {
        ChromeOptions opts = new ChromeOptions();
        opts.addEncodedExtensions(buildExtension());
        ChromeDriver driver = new ChromeDriver(opts);
        driver.get("https://api.ipify.org");
        System.out.println(driver.findElement(
            org.openqa.selenium.By.tagName("body")).getText());
        driver.quit();
    }
}

Sticky sessions

Bake the session token into the username before building the extension. Every request the browser makes during that session exits through the same IP.

python
import secrets

session = secrets.token_hex(8)
user_with_session = f"USER-session-{session}"

options = Options()
options.add_encoded_extension(
    build_proxy_extension(PROXY_HOST, PROXY_PORT, user_with_session, PROXY_PASS)
)
driver = webdriver.Chrome(options=options)
# All page loads, XHR, image fetches — same exit IP.

SSL certificate errors

Our proxy tunnels HTTPS via CONNECT — we never see the TLS handshake. SSL warnings in Selenium are target-side issues, not proxy issues. The standard flag to suppress them for self-signed certs on test targets:

python
# Chrome
options.add_argument("--ignore-certificate-errors")

# Firefox
options.set_preference("webdriver.accept.untrusted.certs", True)
Don't suppress SSL errors in production scraping — a target using a real CA cert should never produce one through our proxy. If it does, check whether the target is serving different content behind a MITM on their end.
Found a gap, or something wrong?
A real human reads support email.