import java.io.IOException;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;
public class Test {
private static class UserAuthenticator extends Authenticator {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
}
public static void main(String[] args) {
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8080");
Authenticator.setDefault(new UserAuthenticator());
//CookieManager cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER);
//CookieHandler.setDefault(cookieManager);
try {
URL url = new URL("http://123.123.123.123");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); //Connection is still close
int code = httpCon.getResponseCode(); //Instead of generating a single request, this generates a bunch of them
} catch (IOException e) {}
}
}
getResponceCode()方法生成多个请求,而不是JavaDocs中所述的单个请求。我用BurpSuite链接了JVM,这是一个非常好的代理,所以我很确定它不是代理问题或者类似的东西。
如果有人能帮助我并解释我为什么会发生,我真的很感激。
我还要提到,如果启用cookie管理器,它只会生成两个请求。第一个获得401响应代码,第二个获得299响应代码(这意味着第二个请求成功)然后停止。 为什么会这样?
此外,在第一个请求中,不会发送任何身份验证凭据,但会在第二个请求之后发送每个请求。 为什么会这样?
[编辑]
我发布了通讯的标题:
不使用cookies:
Request1:
GET / HTTP/1.1
User-Agent: Java/1.8.0_144
Host: 192.168.1.1
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
Response1:
HTTP/1.0 401 Unauthorized
Date: Fri, 10 Nov 2017 11:56:36 GMT
Server: Boa/0.94.13
Connection: close
WWW-Authenticate: Basic realm="H108NS"
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: SESSIONID=4ee8135d;
Request2:
GET / HTTP/1.1
User-Agent: Java/1.8.0_144
Host: 192.168.1.1
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
Connection: close
回应2:
HTTP/1.0 401 Unauthorized
Date: Fri, 10 Nov 2017 11:56:38 GMT
Server: Boa/0.94.13
Connection: close
WWW-Authenticate: Basic realm="H108NS"
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: SESSIONID=2ac98489;
Request2和Response2重复约10-20次。 这没有饼干。尝试使用cookie会发生这种情况:
Request1 with cookies:
GET / HTTP/1.1
User-Agent: Java/1.8.0_144
Host: 192.168.1.1
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
带有cookies的Response1:
HTTP/1.0 401 Unauthorized
Date: Fri, 10 Nov 2017 12:02:01 GMT
Server: Boa/0.94.13
Connection: close
WWW-Authenticate: Basic realm="H108NS"
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: SESSIONID=4b33e52e;
Request2 with cookies:
GET / HTTP/1.1
User-Agent: Java/1.8.0_144
Host: 192.168.1.1
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
Cookie: SESSIONID=4b33e52e
Connection: close
带有cookies的Response2:
HTTP/1.0 200 OK
Content-type: text/html;charset=ISO-8859-1
答案 0 :(得分:1)
您所描述的是具有身份验证的HTTP如何工作。第一个请求发生时没有凭据。具有状态代码401的服务器的响应告诉客户端需要认证,并且还包含支持/接受认证机制的信息。客户端使用此信息创建后续请求,包括身份验证。
根据身份验证机制,您可能会看到两个以上的请求,例如: NTLM导致几个请求 - 响应周期。在您的情况下,我假设确实发生了BASIC或DIGEST身份验证。
因为HTTP是无状态的,所有请求都需要身份验证信息,这就是所有后续请求也包含凭据的原因。这取决于机制,例如再次使用NTLM,请求中的细节看起来不同。
要了解发生了什么,您可以启动一个像Wireshark这样的网络分析器,您可以在其中查看每个erquest /响应周期的请求和响应。
使用您提供的跟踪,似乎服务器需要您的cookie值来在身份验证后跟踪您的会话。这就是为什么你得到“401 Unauthorized”作为回应。
答案 1 :(得分:-1)
我刚刚发现我的JVM使用的是sun.net.www.protocol.http.HttpURLConnection,作为java.net.HttpURLConnection的一个实现,这是一个充满bug的类。您可能想看一下我发现有帮助的post。
实际上有一种方法可以解决这个问题,但仅限于发送 POST 请求的情况。这是通过将JVM属性sun.net.http.retryPost
设置为false
。这可以通过System.setProperty("sun.net.http.retryPost", "false")
在我的情况下,我无法找到解决我的问题的任何方法,但无论如何它只是一些额外的GET请求,jsut会增加你的流量一点点,并不像一些POST那样灾难性的要求重复。
PS:如果有人有一些建议/解决方案,我会很高兴听到它们。