Me gustaría proporcionar una respuesta para el caso de que no tenga control sobre el código que abre la conexión. Como lo hice al usar el URLClassLoaderpara cargar un archivo jar desde un servidor protegido con contraseña.
La Authenticatorsolución funcionaría, pero tiene el inconveniente de que primero intenta llegar al servidor sin una contraseña y solo después de que el servidor solicite una contraseña. Es un viaje de ida y vuelta innecesario si ya sabe que el servidor necesitaría una contraseña.
public class MyStreamHandlerFactory implements URLStreamHandlerFactory {
private final ServerInfo serverInfo;
public MyStreamHandlerFactory(ServerInfo serverInfo) {
this.serverInfo = serverInfo;
}
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
switch (protocol) {
case "my":
return new MyStreamHandler(serverInfo);
default:
return null;
}
}
}
public class MyStreamHandler extends URLStreamHandler {
private final String encodedCredentials;
public MyStreamHandler(ServerInfo serverInfo) {
String strCredentials = serverInfo.getUsername() + ":" + serverInfo.getPassword();
this.encodedCredentials = Base64.getEncoder().encodeToString(strCredentials.getBytes());
}
@Override
protected URLConnection openConnection(URL url) throws IOException {
String authority = url.getAuthority();
String protocol = "http";
URL directUrl = new URL(protocol, url.getHost(), url.getPort(), url.getFile());
HttpURLConnection connection = (HttpURLConnection) directUrl.openConnection();
connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
return connection;
}
}
Esto registra un nuevo protocolo myque se reemplaza httpcuando se agregan las credenciales. Entonces, al crear el nuevo URLClassLoadersolo reemplace httpcon myy todo está bien. Sé que URLClassLoaderproporciona un constructor que toma un URLStreamHandlerFactorypero esta fábrica no se usa si la URL apunta a un archivo jar.