天天看點

使用User-Agent防止HttpClient發送http請求時403 Forbidden和安全攔截

問題的抛出

今天有合作商戶反映,批付交易完成後,在我方伺服器以“伺服器點對點通信”的方式通知請求對方伺服器時,對方攔截了請求。并貼了一張截圖。

使用User-Agent防止HttpClient發送http請求時403 Forbidden和安全攔截

從截圖可以看出來,對方攔截了我們的user-agent(Apache-HttpClient)。

什麼是User-Agent?通常我們用浏覽器通路一個網頁,當我們向伺服器發送請求時,浏覽器會将一些頭資訊附加上,然後發給伺服器,其中就包括User-Agent。一些網站的網頁,為了防止爬蟲或惡意通路,會首先判斷請求頭的User-Agent,如果不是浏覽器請求,則會直接拒絕請求。(裡也提到,直接用HttpClient發起請求csdn時,會收到403 Forbidden)

不同版本的谷歌浏覽器的User-Agent:

Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36

Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)

使用User-Agent防止HttpClient發送http請求時403 Forbidden和安全攔截

解決問題

通過分析httputil代碼,發現我方并未設定請求頭的user-agent屬性。 原來,經模拟點對點請求的測試證明,如果不設定的話,它的值預設是:Apache-HttpClient。

技術支援同僚為了照顧合作商戶的感受,建議我方改一下。那麼,自然是加上user-agent來模拟正常的浏覽器請求客戶伺服器就可以了。

當然,單從技術角度來看,另一個同僚的給的建議也許更好:因為這是個伺服器點對點通信,是以若要從安全方面控制,應該通過諸如ip白名單的方式,而不是通過User-Agent判斷是不是浏覽器請求。

httputil代碼(user-agent不區分大小寫):

;
    HttpGet httpGet = new HttpGet(url);
    httpGet.setHeader("User-Agent",userAgent);
    response = httpclient.execute(httpGet);      
getHttpClient();
    。。。。。
    HttpPost post = new HttpPost(url);
    post.setHeader("user-agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
    CloseableHttpResponse httpResponse = httpClient.execute(post);      
new URL(url);
    HttpURLConnection uc = (HttpURLConnection) urls.openConnection();
    uc.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
    。。。
    uc.setRequestMethod("POST");
    。。。      

繼續閱讀