连接到需要使用 Java 进行身份验证的远程 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/496651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Connecting to remote URL which requires authentication using Java
提问by user14128
How do I connect to a remote URL in Java which requires authentication. I'm trying to find a way to modify the following code to be able to programatically provide a username/password so it doesn't throw a 401.
如何在 Java 中连接到需要身份验证的远程 URL。我正在尝试找到一种方法来修改以下代码,以便能够以编程方式提供用户名/密码,这样它就不会抛出 401。
URL url = new URL(String.format("http://%s/manager/list", _host + ":8080"));
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
采纳答案by James Van Huis
You can set the default authenticator for http requests like this:
您可以为 http 请求设置默认身份验证器,如下所示:
Authenticator.setDefault (new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication ("username", "password".toCharArray());
}
});
Also, if you require more flexibility, you can check out the Apache HttpClient, which will give you more authentication options (as well as session support, etc.)
此外,如果您需要更多的灵活性,您可以查看Apache HttpClient,它将为您提供更多的身份验证选项(以及会话支持等)
回答by Wanderson Santos
There's a native and less intrusive alternative, which works only for your call.
有一种原生的、侵入性较小的替代方案,仅适用于您的通话。
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();
回答by gloo
You can also use the following, which does not require using external packages:
您还可以使用以下不需要使用外部包的内容:
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();
回答by javabeangrinder
If you are using the normal login whilst entering the username and password between the protocol and the domain this is simpler. It also works with and without login.
如果您在协议和域之间输入用户名和密码时使用普通登录,这会更简单。它也适用于登录和不登录。
Sample Url: http://user:[email protected]/url
示例网址: http://user:[email protected]/url
URL url = new URL("http://user:[email protected]/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();
Please note in the comment, from valerybodak, below how it is done in an Android development environment.
请在来自 valerybodak 的评论中注意它是如何在 Android 开发环境中完成的。
回答by lboix
Be really careful with the "Base64().encode()"approach, my team and I got 400 Apache bad request issues because it adds a \r\n at the end of the string generated.
使用“Base64().encode()”方法时要非常小心,我和我的团队遇到了 400 个 Apache 错误请求问题,因为它在生成的字符串末尾添加了一个 \r\n。
We found it sniffing packets thanks to Wireshark.
由于 Wireshark,我们发现它可以嗅探数据包。
Here is our solution :
这是我们的解决方案:
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()));
}
Hope it helps!
希望能帮助到你!
回答by DaniEll
As i have came here looking for an Android-Java-Answer i am going to do a short summary:
当我来到这里寻找 Android-Java-Answer 时,我将做一个简短的总结:
- Use java.net.Authenticatoras shown by James van Huis
- Use Apache Commons HTTP Client, as in this Answer
- Use basic java.net.URLConnectionand set the Authentication-Header manually like shown here
- 使用java.net.Authenticator如James van Huis所示
- 使用Apache Commons HTTP Client,如本答案所示
- 使用基本java.net.URLConnection中并手动设置认证报头所示一样在这里
If you want to use java.net.URLConnectionwith Basic Authentication in Androidtry this code:
如果您想在Android 中使用java.net.URLConnection和基本身份验证,请尝试以下代码:
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
回答by Emmanuel Mtali
ANDROD IMPLEMENTATIONA complete method to request data/string response from web service requesting authorization with username and password
ANDROD 实现从 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();
}
}
}
}
回答by Sarith Nob
Use this code for basic authentication.
使用此代码进行基本身份验证。
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();
回答by FLUXparticle
I'd like to provide an answer for the case that you do not have control over the code that opens the connection. Like I did when using the URLClassLoader
to load a jar file from a password protected server.
对于您无法控制打开连接的代码的情况,我想提供一个答案。就像我在使用URLClassLoader
从受密码保护的服务器加载 jar 文件时所做的那样。
The Authenticator
solution would work but has the drawback that it first tries to reach the server without a password and only after the server asks for a password provides one. That's an unnecessary roundtrip if you already know the server would need a password.
该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;
}
}
This registers a new protocol my
that is replaced by http
when credentials are added. So when creating the new URLClassLoader
just replace http
with my
and everything is fine. I know URLClassLoader
provides a constructor that takes an URLStreamHandlerFactory
but this factory is not used if the URL points to a jar file.
这将注册一个新协议my
,该协议http
在添加凭据时被替换。因此,在创建新的时URLClassLoader
只需替换http
为my
,一切都很好。我知道URLClassLoader
提供了一个构造函数,URLStreamHandlerFactory
但如果 URL 指向一个 jar 文件,则不会使用该工厂。
回答by Syed Danish Haider
i did that this way you need to do this just copy paste it be happy
我是这样做的,你需要这样做只是复制粘贴它很高兴
HttpURLConnection urlConnection;
String url;
// String data = json;
String result = null;
try {
String username ="[email protected]";
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", "[email protected]");
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();
}