Подключение к удаленному URL, который требует аутентификации с помощью Java
Как мне подключиться к удаленному URL в Java, который требует аутентификации. Я пытаюсь найти способ изменить следующий код, чтобы иметь возможность программно предоставить имя пользователя/пароль, чтобы он не бросал 401.
URL url = new URL(String.format("http://%s/manager/list", _host + ":8080"));
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
11 ответов:
вы можете установить Аутентификатор по умолчанию для http-запросов следующим образом:
Authenticator.setDefault (new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication ("username", "password".toCharArray()); } });
кроме того, если вам требуется больше гибкости, вы можете проверить Apache HttpClient, что даст вам больше возможностей аутентификации (а также поддержку сеанса и т. д.)
есть родная и менее навязчивая альтернатива, которая работает только для вашего звонка.
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();
вы также можете использовать следующее, что не требует использования внешних пакетов:
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();
Если вы используете обычный логин при вводе имени пользователя и пароля между протоколом и доменом, это проще. Он также работает с логином и без него.
пример 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();
поскольку я пришел сюда в поисках Android-Java-ответа, я собираюсь сделать краткое резюме:
- использовать Ява.чистая.Аутентификатор Как показал James van Huis
- использовать Apache Commons HTTP Client, а в ответ
- использовать основные Ява.чистая.URLConnection и настройка проверки подлинности заголовка вручную, как показано здесь
Если вы хотите использовать Ява.чистая.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
будьте очень осторожны с " 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())); }
надеюсь, что это помогает!
используйте этот код для обычной проверки подлинности.
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();
Я хотел бы дать ответ на случай, если у вас нет контроля над кодом, который открывает соединение. Как я сделал при использовании
URLClassLoader
для загрузки файла jar с защищенного паролем сервера.The
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.
РЕАЛИЗАЦИЯ ANDROD Полный метод запроса данных / строкового ответа от веб-службы, запрашивающего авторизацию с именем пользователя и паролем
public static String getData(String uri, String userName, String userPassword) { BufferedReader reader = null; byte[] loginBytes = (userName + ":" + userPassword).getBytes(); StringBuilder loginBuilder = new StringBuilder() .append("Basic ") .append(Base64.encodeToString(loginBytes, Base64.DEFAULT)); try { URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.addRequestProperty("Authorization", loginBuilder.toString()); StringBuilder sb = new StringBuilder(); reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = reader.readLine())!= null){ sb.append(line); sb.append("\n"); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if (null != reader){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
Я сделал это таким образом, что вам нужно сделать это просто скопировать и вставить его быть счастливым
HttpURLConnection urlConnection; String url; // String data = json; String result = null; try { String username ="danish.hussain@gmail.com"; String password = "12345678"; String auth =new String(username + ":" + password); byte[] data1 = auth.getBytes(UTF_8); String base64 = Base64.encodeToString(data1, Base64.NO_WRAP); //Connect urlConnection = (HttpURLConnection) ((new URL(urlBasePath).openConnection())); urlConnection.setDoOutput(true); urlConnection.setRequestProperty("Content-Type", "application/json"); urlConnection.setRequestProperty("Authorization", "Basic "+base64); urlConnection.setRequestProperty("Accept", "application/json"); urlConnection.setRequestMethod("POST"); urlConnection.setConnectTimeout(10000); urlConnection.connect(); JSONObject obj = new JSONObject(); obj.put("MobileNumber", "+97333746934"); obj.put("EmailAddress", "danish.hussain@mee.com"); obj.put("FirstName", "Danish"); obj.put("LastName", "Hussain"); obj.put("Country", "BH"); obj.put("Language", "EN"); String data = obj.toString(); //Write OutputStream outputStream = urlConnection.getOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8")); writer.write(data); writer.close(); outputStream.close(); int responseCode=urlConnection.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { //Read BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8")); String line = null; StringBuilder sb = new StringBuilder(); while ((line = bufferedReader.readLine()) != null) { sb.append(line); } bufferedReader.close(); result = sb.toString(); }else { // return new String("false : "+responseCode); new String("false : "+responseCode); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); }
начиная с 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()); } });