连接到需要使用 Java 进行身份验证的远程 URL

如何连接到 Java 中需要身份验证的远程 URL。我试图找到一种方法来修改以下代码,以便能够通过编程提供用户名/密码,这样它就不会抛出一个401。

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

您可以像下面这样为 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();

如果您使用正常的登录,同时输入协议和域之间的用户名和密码,这是比较简单的。它也可以在登录和不登录的情况下使用。

示例网址: http://user:pass@example.com/URL

URL url = new URL("http://user:pass@example.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();

请在评论中注意,来自 valerybodak,下面是如何在 Android 开发环境中完成的。

小心使用“ 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()));
}

希望能有帮助!

As I have came here looking for an Android-Java-Answer I am going to do a short summary:

  1. 使用 Net. Authenticator,如 James van Huis所示
  2. 使用 Apache Commons HTTP 客户端,就像在 这个答案中一样
  3. 使用基本的 URLConnection并手动设置 Authentication-Header,如所示的 给你

如果您想在 仿生人中使用带有基本身份验证的 URLConnection,请尝试以下代码:

URL url = new URL("http://www.example.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

安卓系统实现 从 Web 服务请求用户名和密码授权的数据/字符串响应的完整方法

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

使用此代码进行基本身份验证。

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 文件时所做的那样。

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只是取代 httpmy和一切都很好。我知道 URLClassLoader提供了一个接受 URLStreamHandlerFactory的构造函数,但是如果 URL 指向一个 jar 文件,则不使用这个工厂。

我做到了这一点,你需要这样做,只是复制粘贴它是快乐的

    HttpURLConnection urlConnection;
String url;
//   String data = json;
String result = null;
try {
String username ="user@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@example.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();
}

从 Java9开始,您就可以这样做了

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

能够使用 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 包。