|
jieh
《騎士團團長》
文章: 6881
v3.8.8
|
|
|
|
使用 Apache HttpClient 通過 Form-Based 認證
來源
Form-Based 認證相對 HTTP Basic 認證而言過程較為複雜,需要開發者記錄下相關的 cookie 資訊和部分 header 欄位並多次向站點發出請求。它的大致原理如下:
假定我 們需要訪問的受保護資源為 www.sample.com/sampleApp/sample.rss。首先我們需要向此保護資源發出請求。而由 Form-Based 認證原理一節中可知,J2EE 伺服器會將此請求重定向至 login.jsp。如果仔細分析 login.jsp 我們能發現它僅僅是一個 HTML 表單,其中有兩個欄位 j_username 和 j_password 分別記錄用戶名和密碼,而提交的目標則是 j_security_check。通常情況下,J2EE 構架會在每個站點應用的根節點定義一個 j_security_check 的資源。而我們的站點的應用程式根(Application Root)為 sampleApp。因而,通過將用戶名,密碼以及相關 cookie 和 header 欄位以 POST 方式發送至 www.sample.com/sampleApp/j_security_check 即可通過站點認證。在通過站點認證後,伺服器端將給出一個新的重定向,通常它將指向了用戶最初試圖訪問的受保護資源(本例中也就是 www.sample.com/sampleApp/sample.rss)。我們只需要再次創建訪問物件向此資源發出請求即可獲得其內容。
HttpClient client = new HttpClient(); client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
// 1 GetMethod authget = new GetMethod("httpwww.sample.comsampleAppsample.rss"); try { client.executeMethod(authget); } catch (HttpException httpe) { httpe.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); }
// 2 NameValuePair[] data = new NameValuePair[2]; data[0] = new NameValuePair("j_username", username); data[1] = new NameValuePair("j_password", password);
PostMethod authpost = new PostMethod("http://www.sample.com/sampleApp/j_security_check"); authpost.setRequestBody(data);
// 3 Header hCookie = authget.getRequestHeader("Cookie"); Header hHost = authget.getRequestHeader("Host"); Header hUserAgent = authget.getRequestHeader("User-Agent"); if (hCookie == null || hHost == null || hUserAgent == null) { return null; }
authpost.setRequestHeader(hCookie); authpost.setRequestHeader(hHost); authpost.setRequestHeader(hUserAgent);
authget.releaseConnection();
try { client.executeMethod(authpost);
// 4 Header header = authpost.getResponseHeader("location"); if (header != null) { String newuri = header.getValue(); GetMethod redirect = new GetMethod(newuri);
client.executeMethod(redirect); // process the content from the response redirect.releaseConnection(); } } catch (HttpException httpe) { httpe.printStackTrace(); return null; } catch (IOException ioe) { ioe.printStackTrace(); return null; } authpost.releaseConnection();
其中各個步驟解釋如下: 1. 使用 GET 方式請求 sample.rss。伺服器收到連接後將在回應中給出連接資訊,HttpClient 在接收到回應後會將其保存至 cookie 中。 2. 準備第二次對 j_security_check 的連接,將用戶名和密碼填入新的 POST 請求的正文。 3. 將 cookie 和部分 header 欄位拷貝至新請求的報頭中,並發送請求。 4. 從認證成功的回應中獲取重定向,並對重定向指向的資源發出請求,獲取並處理內容。
----------------------------------------
支持小惡魔 BTC : 19tn3RnCuwZVukXAwyhDWZD4uBgUZoGJPx LTC : LTFa17pSvvoe3aU5jbmfcmEpo1xuGa9XeA 知識跟八卦一樣,越多人知道越有價值;知識最好的備份方法,散播! 藍色小惡魔(林永傑): 臉書
|
|