Gostaria de fornecer uma resposta para o caso de você não ter controle sobre o código que abre a conexão. Como eu fiz ao usar oURLClassLoader
para carregar um arquivo jar de um servidor protegido por senha.
A Authenticator
solução funcionaria, mas tem a desvantagem de tentar primeiro acessar o servidor sem uma senha e somente depois que o servidor solicitar uma senha forneça uma. Essa é uma ida e volta desnecessária se você já sabe que o servidor precisaria de uma senha.
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;
}
}
Isso registra um novo protocolo my
que é substituído por http
quando as credenciais são adicionadas. Portanto, ao criar o novo, URLClassLoader
basta substituir http
por my
e está tudo bem. Eu sei que URLClassLoader
fornece um construtor que leva um, URLStreamHandlerFactory
mas esta fábrica não é usada se o URL aponta para um arquivo jar.