Скачать файл из интернета, используя Java: Как пройти аутентификацию?
Благодаря этой теме Как скачать и сохранить файл из Интернета с помощью Java? Я знаю, как загрузить файл, теперь моя проблема в том, что мне нужно пройти аутентификацию на сервере, с которого я загружаю файлы. Это http-интерфейс к серверу Subversion. В какое поле мне нужно посмотреть?
Используя код, размещенный в последнем комментарии, я получаю это исключение:
java.io.IOException: Server returned HTTP response code: 401 for URL: http://myserver/systemc-2.0.1.tgz
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1305)
at java.net.URL.openStream(URL.java:1009)
at mypackage.Installer.installSystemc201(Installer.java:29)
at mypackage.Installer.main(Installer.java:38)
Спасибо,
6 ответов
Вы расширяете класс Authenticator и регистрируете его. Javadocs по ссылке объясняют, как.
Я не знаю, работает ли это с методом nio, который получил принятый ответ на вопрос, но он наверняка работает по старомодному пути, который был ответом по этому вопросу.
В реализации класса authenticator вы, вероятно, собираетесь использовать PasswordAuthentication и переопределить метод getPasswordAuthentication() вашей реализации Authenticator, чтобы вернуть его. Это будет класс, которому передаются имя пользователя и пароль, которые вам нужны.
По вашему запросу вот пример кода:
public static final String USERNAME_KEY = "username";
public static final String PASSWORD_KEY = "password";
private final PasswordAuthentication authentication;
public MyAuthenticator(Properties properties) {
String userName = properties.getProperty(USERNAME_KEY);
String password = properties.getProperty(PASSWORD_KEY);
if (userName == null || password == null) {
authentication = null;
} else {
authentication = new PasswordAuthentication(userName, password.toCharArray());
}
}
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
И вы регистрируете его в методе main (или где-то вдоль строки перед вызовом URL):
Authenticator.setDefault(new MyAuthenticator(properties));
Использование простое, но я нахожу API запутанным и отчасти задом наперед, как вы обычно думаете об этих вещах. Довольно типично для синглтон-дизайна.
Это некоторый код, который я написал, который выбирает веб-сайт и отображает содержимое в System.out. Использует обычную аутентификацию:
import java.net.*;
import java.io.*;
public class foo {
public static void main(String[] args) throws Exception {
URL yahoo = new URL("http://www.MY_URL.com");
String passwdstring = "USERNAME:PASSWORD";
String encoding = new
sun.misc.BASE64Encoder().encode(passwdstring.getBytes());
URLConnection uc = yahoo.openConnection();
uc.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = (InputStream)uc.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println (line);
}
in.close();
}
Проблемы с приведенным выше кодом:
Этот код не готов к работе (но он дает понять смысл).
Код выдает это предупреждение компилятора:
foo.java:11: предупреждение: sun.misc.BASE64Encoder является проприетарным API Sun и может быть удалено в будущем выпуске. Sun.misc.BASE64Encoder() закодировать (passwdstring.getBytes()); ^ 1 предупреждение
На самом деле нужно использовать класс Authenticator, но я не мог понять, как, и не мог найти ни одного примера, который просто показывает, что людям на Java это не нравится, когда вы используете их. язык делать классные вещи.:-П
Таким образом, вышеупомянутое не является хорошим решением, но оно работает и может быть легко изменено позже.
Напишите свой основной класс для Authenticator:
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class MyAuthenticator extends Authenticator {
private static String username = "";
private static String password = "";
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication (MyAuthenticator.username,
MyAuthenticator.password.toCharArray());
}
public static void setPasswordAuthentication(String username, String password) {
MyAuthenticator.username = username;
MyAuthenticator.password = password;
}
}
Напишите свой основной класс:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;
public class MyMain{
public static void main(String[] args) {
URL url;
InputStream is = null;
BufferedReader br;
String line;
// Install Authenticator
MyAuthenticator.setPasswordAuthentication("Username", "Password");
Authenticator.setDefault (new MyAuthenticator ());
try {
url = new URL("Your_URL_Here");
is = url.openStream(); // throws an IOException
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (is != null) is.close();
} catch (IOException ioe) {
// nothing to see here
}
}
}
}
Вы пытались создать свой URL в виде http://user:password@domain/path?
Я хотел бы предложить проверить HttpClient от apache http://hc.apache.org/httpclient-3.x/ что делает загрузку / аутентификацию очень простой
Эта библиотека с открытым исходным кодом, http://spnego.sourceforge.net/, также имеет несколько примеров того, как использовать ее класс SpnegoHttpURLConnection.
Один из конструкторов в классе позволяет передавать имя пользователя и пароль.
Посмотрите на java-документ класса для примеров.