Подключение к удаленному URL, который требует аутентификации с использованием Java - PullRequest
113 голосов
/ 30 января 2009

Как мне подключиться к удаленному URL в Java, который требует аутентификации. Я пытаюсь найти способ изменить следующий код, чтобы иметь возможность программно предоставить имя пользователя / пароль, чтобы он не выдавал 401.

URL url = new URL(String.format("http://%s/manager/list", _host + ":8080"));
HttpURLConnection connection = (HttpURLConnection)url.openConnection();

Ответы [ 12 ]

125 голосов
/ 30 января 2009

Вы можете установить аутентификатор по умолчанию для http-запросов, например:

Authenticator.setDefault (new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication ("username", "password".toCharArray());
    }
});

Также, если вам требуется больше гибкости, вы можете проверить Apache HttpClient , который предоставит вам больше опций аутентификации (а также поддержку сеансов и т.

114 голосов
/ 28 февраля 2011

Есть собственная и менее навязчивая альтернатива, которая работает только для вашего звонка.

URL url = new URL(“location address”);
URLConnection uc = url.openConnection();
String userpass = username + ":" + password;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();
78 голосов
/ 26 сентября 2012

Вы также можете использовать следующее, которое не требует использования внешних пакетов:

URL url = new URL(“location address”);
URLConnection uc = url.openConnection();

String userpass = username + ":" + password;
String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

uc.setRequestProperty ("Authorization", basicAuth);
InputStream in = uc.getInputStream();
37 голосов
/ 29 октября 2012

Если вы используете обычный логин при вводе имени пользователя и пароля между протоколом и доменом, это проще. Он также работает с и без входа в систему.

URL-адрес образца: http://user:pass@domain.com/url

URL url = new URL("http://user:pass@domain.com/url");
URLConnection urlConnection = url.openConnection();

if (url.getUserInfo() != null) {
    String basicAuth = "Basic " + new String(new Base64().encode(url.getUserInfo().getBytes()));
    urlConnection.setRequestProperty("Authorization", basicAuth);
}

InputStream inputStream = urlConnection.getInputStream();
8 голосов
/ 06 декабря 2014

Поскольку я пришел сюда в поисках Android-Java-ответа, я собираюсь сделать краткое резюме:

  1. Использование java.net.Authenticator , как показано Джеймс ван Хьюис
  2. Использовать HTTP-клиент Apache Commons , как в этот ответ
  3. Используйте базовый java.net.URLConnection и установите заголовок аутентификации вручную, как показано здесь

Если вы хотите использовать java.net.URLConnection с базовой аутентификацией в Android , попробуйте этот код:

URL url = new URL("http://www.mywebsite.com/resource");
URLConnection urlConnection = url.openConnection();
String header = "Basic " + new String(android.util.Base64.encode("user:pass".getBytes(), android.util.Base64.NO_WRAP));
urlConnection.addRequestProperty("Authorization", header);
// go on setting more request headers, reading the response, etc
3 голосов
/ 29 мая 2017

Используйте этот код для базовой аутентификации.

URL url = new URL(path);
String userPass = "username:password";
String basicAuth = "Basic " + Base64.encodeToString(userPass.getBytes(), Base64.DEFAULT);//or
//String basicAuth = "Basic " + new String(Base64.encode(userPass.getBytes(), Base64.No_WRAP));
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.connect();
3 голосов
/ 06 июня 2014

Будьте очень осторожны с подходом "Base64 (). Encode ()", моя команда и я получили 400 проблем с неверными запросами Apache, потому что они добавляют \ r \ n в конце сгенерированной строки.

Мы обнаружили, что он нюхает пакеты благодаря Wireshark.

Вот наше решение:

import org.apache.commons.codec.binary.Base64;

HttpGet getRequest = new HttpGet(endpoint);
getRequest.addHeader("Authorization", "Basic " + getBasicAuthenticationEncoding());

private String getBasicAuthenticationEncoding() {

        String userPassword = username + ":" + password;
        return new String(Base64.encodeBase64(userPassword.getBytes()));
    }

Надеюсь, это поможет!

2 голосов
/ 01 января 2018

Я хотел бы дать ответ на тот случай, если вы не можете контролировать код, открывающий соединение. Как и при использовании URLClassLoader для загрузки файла JAR с сервера, защищенного паролем.

Решение Authenticator будет работать, но имеет недостаток, заключающийся в том, что сначала он пытается получить доступ к серверу без пароля, и только после того, как сервер запрашивает его. Это ненужный прием, если вы уже знаете, что серверу понадобится пароль.

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;
    }

}

Регистрирует новый протокол my, который заменяется на http при добавлении учетных данных. Поэтому при создании нового URLClassLoader просто замените http на my, и все в порядке. Я знаю, что URLClassLoader предоставляет конструктор, который принимает URLStreamHandlerFactory, но эта фабрика не используется, если URL указывает на файл jar.

1 голос
/ 19 июля 2018

Начиная с Java 9, вы можете сделать это

URL url = new URL("http://www.example.com");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setAuthenticator(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication ("USER", "PASS".toCharArray());
    }
});
0 голосов
/ 26 марта 2019

удалось установить аутентификацию с помощью HttpsURLConnection

           URL myUrl = new URL(httpsURL);
            HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
            String userpass = username + ":" + password;
            String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
            //httpsurlconnection
            conn.setRequestProperty("Authorization", basicAuth);

несколько изменений, извлеченных из этого поста. и Base64 из пакета java.util.

...