Java代理407错误:检查CONNECT的Basic认证
将Java代理凭据限制在指定代理范围内,并检查JDK针对HTTPS CONNECT隧道的独立Basic认证策略。
反复出现407,不一定意味着Java发送了错误的密码。JDK参考实现通常会禁用HTTPS CONNECT隧道的Basic认证。仅提供Basic的代理可能在认证回调提供凭据之前就被拒绝。
限制凭据回调的作用范围
为Java HTTP客户端设置Authenticator,并将其限制在已配置的代理上:
String proxyHost = "203.0.113.10";
int proxyPort = 8080;
String password = System.getenv("PROXY_PASSWORD");
if (password == null) {
throw new IllegalStateException("Set PROXY_PASSWORD");
}
java.net.Authenticator auth = new java.net.Authenticator() {
@Override
protected java.net.PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType() == RequestorType.PROXY
&& proxyHost.equals(getRequestingHost())
&& proxyPort == getRequestingPort()) {
return new java.net.PasswordAuthentication(
"proxy-user", password.toCharArray());
}
return null;
}
};
java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
.proxy(java.net.ProxySelector.of(
new java.net.InetSocketAddress(proxyHost, proxyPort)))
.authenticator(auth)
.connectTimeout(java.time.Duration.ofSeconds(5))
.build();
这段代码用于配置单个客户端,并非设置全局默认认证器。请替换文档示例地址,使用该服务实际提供的凭据。对请求方类型和端点的检查,可避免同一个回调在应答网站认证质询时随意提供代理账号。
检查失败发生在哪个认证阶段
JDK分别为普通HTTP代理转发和CONNECT隧道设置了禁用认证方案的选项,相关名称为jdk.http.auth.proxying.disabledSchemes和jdk.http.auth.tunneling.disabledSchemes。
这解释了为什么HTTP流量能够通过认证,而经由同一个代理的HTTPS隧道却会失败。请检查运行时的conf/net.properties和部署策略,不要假定另一台机器的实际默认设置也相同。
全局清空禁用方案列表并不是通用的代理修复方法。发送给明文HTTP代理的Basic凭据,不会受到随后与目标建立的TLS连接保护。批准变更前,请审视代理传输方式、认证方法和部署策略。
JDK文档中说明的内置认证行为,也不代表它承诺支持代理声明的每一种认证方案。手动提供Authorization或Proxy-Authorization请求头会改变自动认证器的处理流程,因此当回调行为与示例不同时,请检查自定义请求头。