Loading KAIROXO page正在加载 KAIROXO 页面Đang tải trang KAIROXO

KAIROXO
Tutorial

OkHttp Proxy Authentication: CONNECT, Timeouts and Pools

Route Java requests through an HTTP proxy, answer proxy authentication correctly and keep connection ownership clear across workers.

KAIROXO

A close-up of source code on a computer screen.

OkHttp proxy authentication belongs to the connection between your Java application and the proxy. It is different from signing in to the destination website. Mixing those responsibilities can expose credentials to the wrong server or create an endless sequence of failed retries. A reliable integration starts by making the route, challenge handler and client lifecycle explicit.

Consider a worker that collects approved public pages for a reporting pipeline. The worker already knows how to parse responses, but now needs a particular network exit. You do not need to rewrite the parser. Configure an OkHttpClient for that access profile, verify the resulting route with a controlled probe, and then introduce it to the existing workload gradually.

Understand the two authentication boundaries

A destination normally uses 401 to request application authentication, while a proxy uses 407 for proxy authentication. OkHttp exposes separate authenticator and proxyAuthenticator hooks because the two challenges belong to different parties. Put proxy credentials in Proxy-Authorization through the proxy hook, not into the destination's Authorization header. Do not assume that a successful website login configures the proxy.

For HTTPS destinations, an HTTP proxy commonly receives a CONNECT request before the encrypted connection to the destination is established. Confirm that the endpoint supports this workflow. The proxy protocol, the destination URL scheme and the IP product are separate choices. A residential address does not automatically imply a particular protocol or authentication mechanism.

Implementation steps

  1. Define a profile with external credentials

    Read the proxy host, port and credentials from trusted deployment configuration. Validate the port before starting a worker, and keep the profile identifier separate from the secret values. The example uses individual environment variables so logs can identify configuration problems without printing an authenticated URL. Restrict access to those variables like any other service credential.

    Choose an authorized probe endpoint with a small response and an expected observation. If the goal is exit verification, the endpoint should report the address it observed. A later content check should use a permitted destination and a known field. Keeping these tests separate prevents a valid route from being mistaken for successful extraction.

  2. Configure one bounded client

    Use Proxy.Type.HTTP for the HTTP proxy path in this example. The proxyAuthenticator returns a new request carrying the proxy header and stops if that header was already attempted. That stop condition matters: repeatedly returning the same rejected credential cannot repair a bad password. OkHttp may also invoke the proxy authenticator for its preemptive CONNECT challenge; the handler should remain narrow and predictable.

    The client sets connection, read and whole-call timeouts. Connection retry is disabled here to make a diagnostic request easy to interpret. A production retry policy should be deliberate, bounded and aware of method safety. Keep the normal TLS trust configuration. None of these controls turn a timeout or certificate failure into a reason to disable verification.

    Codejava
    import java.net.InetSocketAddress;import java.net.Proxy;import java.util.concurrent.TimeUnit;import okhttp3.Credentials;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response; public final class ProxyProbe {    private static String required(String name) {        String value = System.getenv(name);        if (value == null || value.isBlank()) throw new IllegalArgumentException("missing " + name);        return value;    }     public static void main(String[] args) throws Exception {        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(                required("PROXY_HOST"), Integer.parseInt(required("PROXY_PORT"))));        String credential = Credentials.basic(required("PROXY_USER"), required("PROXY_PASSWORD"));        OkHttpClient client = new OkHttpClient.Builder()                .proxy(proxy)                .proxyAuthenticator((route, response) -> {                    if (response.request().header("Proxy-Authorization") != null) return null;                    return response.request().newBuilder()                            .header("Proxy-Authorization", credential).build();                })                .connectTimeout(8, TimeUnit.SECONDS)                .readTimeout(12, TimeUnit.SECONDS)                .callTimeout(20, TimeUnit.SECONDS)                .retryOnConnectionFailure(false)                .build();        Request request = new Request.Builder().url(required("PROBE_URL")).build();        try (Response response = client.newCall(request).execute()) {            System.out.println("status=" + response.code());        } catch (java.io.IOException error) {            System.out.println("request failed; record a sanitized error category");        } finally {            client.connectionPool().evictAll();            client.dispatcher().executorService().shutdown();        }    }}
  3. Reuse connections with a clear owner

    Create the client when the access profile is initialized and share it across compatible workers. Rebuilding a client for every URL undermines connection reuse and makes latency comparisons misleading. If a job requires a different proxy identity, decide whether it belongs to another client profile instead of mutating a shared object while other requests are active.

    Close every Response, including error responses. In a short command-line probe, shutting down the dispatcher and evicting idle connections is appropriate at the end. In a service, do that when the owning profile is retired, not after every task. Large or incomplete bodies may prevent a connection from being reused; resource cleanup and guaranteed reuse are not the same claim.

  4. Verify outcomes and classify failures

    Run the single probe first, then check the destination with a stable set of headers and session inputs. Record the profile identifier, destination category, elapsed time, status code and a content-validation result. Avoid recording full authenticated URLs, cookies or arbitrary response bodies. If debugging requires a sample, use an approved redaction and retention process rather than unrestricted wire logs.

    A 407 usually sends you back to proxy credentials or access rules. A 401 belongs to the destination's authentication boundary. Timeouts need stage-aware investigation, and a 200 response still needs a useful-content check. Keep these categories visible in reporting so increasing retries does not merely hide a configuration defect behind more traffic and slower jobs.

    • Reject repeated credential attempts instead of creating an authentication loop.
    • Compare profiles with the same destinations, headers and concurrency.
    • Treat response parsing as a separate acceptance stage.
    • Revisit the client lifecycle when profiles or workload requirements change.

Frequently asked questions

Sources and further reading

Related KAIROXO guide

Loading KAIROXO page正在加载 KAIROXO 页面Đang tải trang KAIROXO