You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java原生HttpClient通过带Basic认证代理访问HTTPS资源问题

解决方案

可以通过Java 16内置的HttpClient实现带Basic认证的HTTP代理访问HTTPS资源,你之前的代码存在两处错误导致HTTPS场景返回407状态码:

  • 构造InetSocketAddress时传入了带http://前缀的代理地址,该类仅需要填写纯主机名,不需要scheme前缀
  • 自定义Authenticator没有判断请求类型为代理认证,导致HTTPS隧道建立的CONNECT请求阶段没有携带代理凭证

修正后完整可运行代码

import java.net.*;
import java.net.http.*;
import java.time.Duration;

// 原有ProxySettings定义无需修改
public record ProxySettings(String scheme, String hostname, int port, String userName, String password) {
    public char[] getPasswordArray() {
        return password.toCharArray();
    }

    public String getUri() {
        return scheme + "://" + hostname;
    }
}

public class ProxyHttpsTest {
    public static void main(String[] args) throws Exception {
        // 替换为实际代理参数
        ProxySettings proxySettings = new ProxySettings("http", "proxy.ip.address", 8080, "userName", "password");

        HttpRequest request = HttpRequest.newBuilder(new URI("https://yandex.ru")).build();

        HttpClient client = HttpClient.newBuilder()
                // 修正1:仅传入代理主机名和端口构造InetSocketAddress
                .proxy(ProxySelector.of(new InetSocketAddress(proxySettings.hostname(), proxySettings.port())))
                // 修正2:仅在代理认证请求时返回凭证
                .authenticator(new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        if (getRequestorType() == RequestorType.PROXY) {
                            return new PasswordAuthentication(proxySettings.userName(), proxySettings.getPasswordArray());
                        }
                        return super.getPasswordAuthentication();
                    }
                })
                .connectTimeout(Duration.ofSeconds(10))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("响应状态码:" + response.statusCode());
        System.out.println("响应体:" + response.body());
    }
}

兼容备用方案

如果部分特殊代理对上述Authenticator逻辑兼容性不佳,可手动构造代理认证头实现,无需配置Authenticator:

import java.net.*;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.time.Duration;

// 构造认证头
String authStr = proxySettings.userName() + ":" + proxySettings.password();
String encodedAuth = Base64.getEncoder().encodeToString(authStr.getBytes(StandardCharsets.UTF_8));

HttpRequest request = HttpRequest.newBuilder(new URI("https://yandex.ru"))
        .header("Proxy-Authorization", "Basic " + encodedAuth)
        .build();

// 客户端无需配置authenticator
HttpClient client = HttpClient.newBuilder()
        .proxy(ProxySelector.of(new InetSocketAddress(proxySettings.hostname(), proxySettings.port())))
        .connectTimeout(Duration.ofSeconds(10))
        .build();

内容的提问来源于stack exchange,提问作者Leonis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:24:08