【问题标题】:Cookie management using the Java Apache HttpClient Fluent API使用 Java Apache HttpClient Fluent API 管理 Cookie
【发布时间】:2017-07-05 22:02:16
【问题描述】:

我无法弄清楚如何使用 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 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));
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]}

我在登录后检查了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]

所以我也尝试将 cookie 显式添加到 GET 请求的 Header 中,但仍然失败并出现相同的 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

有任何想法如何使用 fluent API 进行这项工作吗?

【问题讨论】:

    标签: java cookies


    【解决方案1】:

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

    从 4.2 版本开始,HttpClient 带有一个基于流畅接口概念的易于使用的外观 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 {
           ...
    

    【讨论】:

    • 是的,切换到非流利的“冗长”API 是可行的。
    • 我总是尽量避免声明这一点的 API(简化配置而不是功能,如果您希望拥有所有配置选项,则可以使用另一个 API),即使提供的功能已经足够了:如果有一天需要更多配置:1/我不想花几个小时试图弄清楚这个 API 是如何在幕后配置另一个的,2/我不想对以前工作的所有东西进行回归测试(特别是当它涉及到网络时),3/我发现那些 api 在升级版本时往往会更频繁地刹车
    猜你喜欢
    • 2013-10-08
    • 1970-01-01
    • 2013-08-30
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    相关资源
    最近更新 更多