我需要与一个需要身份验证的模糊网络服务器交谈。如果我不提供凭据,则会显示登录表单。但是,如果我提供未经请求的基本身份验证凭据,我会直接获得所需的内容。
wget
直接支持:
# this fails and downloads a form:
wget https://weird.egg/data.txt --http-user=me --http-password=shhh
# this works and downloads the document:
wget https://weird.egg/data.txt --http-user=me --http-password=shhh --auth-no-challenge
现在我的问题是:如何使用Apache的HTTP组件在Java中进行下载?
这是我到目前为止所得到的。 (还有一个代理,我在-Y on
中使用wget
,我有一个匹配的https_proxy
环境变量。)
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import java.net.URI;
// ...
DefaultHttpClient hc = new DefaultHttpClient();
hc.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost(proxy_name, proxy_port));
URI uri = new URI("https://weird.egg/data.txt");
hc..getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME), new UsernamePasswordCredentials("me", "shh"));
hc.execute(new HttpGet(uri)); // etc
但是,我最终只得到登录表单页面,而不是实际文档。我怀疑DefaultHttpClient没有以wget
的方式发送未经请求的凭证。有没有办法让Java程序发送凭证?
答案 0 :(得分:10)
没关系。我通过不尝试使用任何库身份验证方法解决了这个问题,但只是强制执行基本身份验证标头:
HttpGet get = new HttpGet(uri);
String basic_auth = new String(Base64.encodeBase64((username + ":" + password).getBytes()));
get.addHeader("Authorization", "Basic " + basic_auth);
hc.execute(get); // etc
(这需要额外的import org.apache.commons.codec.binary.Base64;
,但我们可以删除与凭据相关的导入。)