Jena 4.3で導入されたJenaのJDKベースHTTPスタックでは、クエリビルダーに渡す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設定があります。CONNECTにおけるJDKのBasic認証の既定値は、そうしたポリシー確認の一つです。

Apache HttpClientとSimpleNTAuthenticatorを使った過去のJenaの例は、より古いtransport世代に属します。企業プロキシが現在のtransportでは使えない認証方式を要求する場合は、その古い認証オブジェクトを現代のビルダーに押し込もうとせず、ネットワーク管理者と相談して対応可能な連携を決めてください。

関連記事