Chciałbym udzielić odpowiedzi dla przypadku, że nie masz kontroli nad kodem, który otwiera połączenie. Link zrobiłem, gdy użyłem URLClassLoader
do załadowania pliku JAR z serwera chronionego hasłem.
Rozwiązanie Authenticator
działałoby, ale ma tę wadę, że najpierw próbuje dotrzeć do serwera bez hasła i dopiero po tym, gdy serwer poprosi o podanie hasła. To niepotrzebny objazd, jeśli już wiesz, że serwer potrzebuje hasł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;
}
}
Rejestruje nowy protokół my
, który jest zastąpiony przez http
gdy poświadczenia są dodawane. Dlatego przy tworzeniu nowego URLClassLoader
wystarczy zamienić http
na my
i wszystko jest w porządku. Wiem, że URLClassLoader
dostarcza konstruktora, który pobiera URLStreamHandlerFactory
, ale ta fabryka nie jest używana, jeśli adres URL wskazuje na plik JAR.
Jak radzisz sobie ze złym uwierzytelnieniem? [Na przykład, jeśli użytkownik podaje poświadczenia uwierzytelniające nazwę użytkownika i hasło, które nie pasują do niczego]? – SK9
Ta odpowiedź uratowała mi dzień! –
Powyższy kod działa, ale jest całkowicie niejawny co do tego, co się dzieje. Tam jest nadpisywanie i nadpisywanie metod tam, kopiuj do dokumentów dla tych klas, jeśli chcesz wiedzieć, co się dzieje. Kod jest bardziej wyraźny [javacodegeeks] (http://examples.javacodegeeks.com/core-java/net/authenticator/access-password-protected-url-with-authenticator/) – Fuchida