使用 Java Apache HttpClient Fluent API 进行 Cookie 管理

quu*_*x00 3 java cookies

我无法弄清楚如何使用 Apache HttpComponents/HttpClient Fluent API 并让它正确地将 cookie 发送回需要登录的 Web 服务器,然后发送回 cookie 以访问网站的其他部分。我使用的是4.5.3版本。

根据 Fluent API 教程,您可以使用 (HttpComponents) 执行器“以便在特定的安全上下文中执行请求,从而缓存身份验证详细信息并重新用于后续请求”。https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/ Fluent.html

所以我尝试了,但在登录后尝试访问另一个页面时,我收到 403 访问被拒绝。这是我尝试过的代码:

CookieStore httpCookieStore = new BasicCookieStore();
List<Cookie> cookies = httpCookieStore.getCookies();

String username = "admin";
String password = "admin";
Executor httpExecutor = Executor.newInstance().auth(username, password);
httpExecutor.use(httpCookieStore);
Response response = httpExecutor.execute(Request.Get("http://myserver.example.com/login").useExpectContinue());
String loginOutput = response.returnContent().asString();
System.out.println(loginOutput);  // works - gets the expected page

String swaggerUrl = "http://myserver.example.com/swagger/index.html";
response = httpExecutor.execute(Request.Get(swaggerUrl));
HttpResponse httpResponse = response.returnResponse();
System.out.println(httpResponse);  // Response is 403 Access Denied
// prints: HttpResponseProxy{HTTP/1.1 403 Access Denied [X-Content-Type-Options: nosniff, X-XSS-Protection: 1; mode=block, Pragma: no-cache, X-Frame-Options: DENY, Content-Type: text/html;charset=ISO-8859-1, Cache-Control: must-revalidate,no-cache,no-store, Content-Length: 1391, Server: Jetty(8.1.16.v20140903)] [Content-Type: text/html; charset=ISO-8859-1,Content-Length: 1391,Chunked: false]}
Run Code Online (Sandbox Code Playgroud)

CookieStore我检查了登录后的内容,它有正确的cookie:

System.out.println(httpCookieStore.getCookies().size()); // prints 1
System.out.println(httpCookieStore.getCookies().get(0)); 
// prints: [version: 0][name: JSESSIONID][value: 14b1yp7hf85es1vc6zpe2y376n][domain: myserver.example.com][path: /][expiry: null]
Run Code Online (Sandbox Code Playgroud)

因此,我还尝试将 cookie 显式添加到 GET 请求的标头,但仍然失败,并出现相同的 403 Access Denied 错误:

CookieStore httpCookieStore = new BasicCookieStore();
List<Cookie> cookies = httpCookieStore.getCookies();

String username = "admin";
String password = "admin";
Executor httpExecutor = Executor.newInstance().auth(username, password);
httpExecutor.use(httpCookieStore);
Response response = httpExecutor.execute(Request.Get("http://myserver.example.com/login").useExpectContinue());
String loginOutput = response.returnContent().asString();
System.out.println(loginOutput);  // works - gets the expected page

String swaggerUrl = "http://myserver.example.com/swagger/index.html";
response = httpExecutor.execute(Request.Get(swaggerUrl).addHeader(authCookieName, authCookieValue));
HttpResponse httpResponse = response.returnResponse();
System.out.println(httpResponse);  // Response is 403 Access Denied
Run Code Online (Sandbox Code Playgroud)

有什么想法可以让这个与 Fluent API 一起工作吗?

Thi*_*rry 5

当查看 HttpClient 文档时,您链接了,他们从这个警告开始(强调我的):

从 4.2 版开始,HttpClient 附带了一个基于流畅接口概念的易于使用的 Facade API。Fluent Facade API 仅公开 HttpClient 最基本的功能,适用于不需要 HttpClient 完全灵活性的简单用例。例如,流畅的门面 API 使用户不必处理连接管理和资源释放。

您很可能会遇到通过 Fluent api 进行的配置不受支持的情况(并回答您从他们的文档中引用的内容,身份验证和会话管理是链接的,但彼此不是强制性的:您可能有一些要求身份验证信息的无状态服务对于每个请求,无需启动会话,并且您显然可以创建会话(由 cookie 支持),而无需询问身份验证信息)

您可能不得不求助于其他更详细的 API:

BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultCookieStore(cookieStore)
    .build();
try {
    HttpGet httpget = new HttpGet("https://someportal/");
    CloseableHttpResponse response1 = httpclient.execute(httpget);
    try {
       ...
Run Code Online (Sandbox Code Playgroud)