2017-07-05 31 views
0

我很難弄清楚如何使用Apache HttpComponents/HttpClient Fluent API並讓它正確地將Cookie發回到需要登錄的Web服務器,然後發回Cookie訪問該網站的其他部分。我正在使用版本4.5.3。使用Java Apache HttpClient Fluent API進行Cookie管理

根據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]} 

我查了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請求頭,但仍然失敗,同樣的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).addHeader(authCookieName, authCookieValue)); 
HttpResponse httpResponse = response.returnResponse(); 
System.out.println(httpResponse); // Response is 403 Access Denied 

任何想法如何使這與流利的API工作?

回答

1

當HttpClient的文檔看,你聯繫,他們開始用此警告(重點煤礦):

As of version of 4.2 HttpClient comes with an easy to use facade API based on the concept of a fluent interface. Fluent facade API exposes only the most fundamental functions of HttpClient and is intended for simple use cases that do not require the full flexibility of HttpClient. For instance, fluent facade API relieves the users from having to deal with connection management and resource deallocation.

你可能會在不支持的配置的情況下,通過流暢的API(並回答你引用來自他們的文檔,認證和會話管理是相互關聯的,但不是彼此強制的:你可能有一些無狀態的服務需要每一個請求的auth信息而沒有開始會話,你可以創建會話(由一個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 { 
     ... 
+0

是的,切換到不流利的「詳細」API工作。 – quux00

+0

我總是儘量避免使用API​​來描述這一點(簡化功能配置,如果希望擁有所有配置選項,則可以使用另一個API),即使提供的功能足夠了:如果有一天需要更多配置:1 /我不想花費數小時的時間試圖弄清楚這個API是如何配置幕後的另一個API的,2 /我不希望迴歸測試以前工作的所有東西(特別是當它涉及到網絡時) ,3 /我發現這些API在升級版本時往往會更頻繁地剎車 – Thierry

相關問題