Jena 4.3+ SPARQL 客户端的代理认证
把代理选择器和认证器附加到现代 Jena 查询执行所使用的 JDK HTTP 客户端上。
对于 Jena 中基于 JDK 的 HTTP 栈(自 Jena 4.3 引入),要配置传给查询构建器的 transport。SPARQL 端点的密码和代理的密码可能由不同的机器索取。
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.http.HttpClient;
import org.apache.jena.sparql.exec.http.QueryExecutionHTTP;
var http = HttpClient.newBuilder()
.proxy(ProxySelector.of(
new InetSocketAddress("proxy.example", 8080)))
.authenticator(proxyAuthenticator)
.build();
var execution = QueryExecutionHTTP.service(endpointUrl)
.httpClient(http)
.query("ASK { ?s ?p ?o }")
.build();这个片段构建一次查询执行。endpointUrl 是实际的 SPARQL 服务 URL;proxyAuthenticator 是应用程序提供的 java.net.Authenticator。请按照应用程序正常的查询生命周期来执行并关闭这次查询执行。
在该认证器的 getPasswordAuthentication 方法中,只有当 getRequestorType() == RequestorType.PROXY 且请求的主机和端口与已配置的中介一致时,才返回代理的 PasswordAuthentication。对无关的质询返回 null。把这个对象附加到客户端上,可以让这一选择只对该客户端生效。
读懂代理在要求什么
407 响应表示出现了代理认证质询。它的 Proxy-Authenticate 头会说明所提供的方案;仅凭状态码无法区分 Basic 与 NTLM 或其他方案。
要把这份方案清单与已部署的 JDK 客户端的能力和认证策略对照。提供用户名和密码并不会凭空增加不受支持的方案。对于 HTTPS 目标,还要检查 JDK 的 jdk.http.auth.tunneling.disabledSchemes 策略;普通 HTTP 代理有单独的 disabledSchemes 设置。JDK 对 CONNECT 的 Basic 认证默认值就是这类策略检查之一。
使用 Apache HttpClient 和 SimpleNTAuthenticator 的历史 Jena 示例属于更早一代的 transport。如果企业代理要求当前 transport 不支持的认证机制,应与网络管理员商定受支持的集成方式,而不是硬把那些旧的认证对象塞进新的构建器。