Basic and Digest Access Authentication (rfc2617) 及HttpClient實現

介紹Basic和Digest

http協議並沒有定義相關的安全認證方面的標準,所以就有了Basic and Digest Access Authentication的定義來補充,它的目的就是補充一套基於http服務端的認證機制,保護相關的資源避免被非法用戶訪問,如果你要訪問被保護的資源,則必需要提供合法的用戶名和密碼。

和https有什麼關聯?

basic & digest auth 和 https 沒有任何關係。前者是爲用戶認證機制,後者是信息通道加密措施。

basic 和 digest有什麼區別?

digest是basic的升級版,更加安全。因爲basic是明文傳輸密碼信息,而digest是加密後傳輸。

digest就是絕對安全的嗎?

首先,這個世界上沒有絕對的東西。digest默認用MD5(其它算法也可以)對密碼進行加密,雖然相比basic認證的明文傳輸更安全,但是加密算法本身的安全性也值得懷疑(md5是可以反推出原文的)。再者,digest只是對認證信息的加密,後續的內容傳輸安全性得不到保障。所以https機制的作用就顯現出來。

通過上面的相關信息,我們可以得到一個清晰的結論:如果你想加強自己的認證信息的保護,有兩種選擇,一是基於digest認證;別一種是在https通道上進行basic認證。

basic和digest認證流程

 

1,客戶端請求受保護的資源
2,服務器檢測到沒有授權,則生成一個challenge返回給客戶端
3,客戶端根據challenge和相關信息計算出digest
4,附帶3計算出的信息再次請求1中的資源
5,服務端根據已知的用戶密碼信息計算出digest並與4中請求的digest比較驗證
6,服務端驗證通過後返回資源給合法用戶

Basic和Digest的認證都是按照上面的流程來,唯一不同的是3和5中計算digest的算法不同:Basic是將密碼直接base64編碼(明文),而Digest是用MD5進行加密後傳輸。

下面假設我們現在要請求:http://localhost:8080/index.html 這個路徑,而它需要認證後才能訪問。


Basic的流程如下:

  1. 在瀏覽器請求:http://localhost:8080/index.html
  2. 服務器返回401(unauthentication)代碼,並附帶一個包含challenge的頭,格式如下:WWW-Authenticate    Basic realm="Admin All"
  3. 瀏覽器用:base64(username:password) 編碼後的信息添加到請求頭中再次請求1中的資源,如果用戶名是tomcat,密碼是tomcat,則base64(tomcat:tomcat)爲(dG9tY2F0OnRvbWNhdA==)。所以頭信息爲:Authorization    Basic dG9tY2F0OnRvbWNhdA==
  4. 用3中計算的請求頭信息再次請求1中的資源
  5. 服務器用3中相同的算法(base64)驗證用戶密碼合法性
  6. 返回index.html的資源

Digest的流程和上面一樣,只是challenge和digest的生成算法不同

  1. 在瀏覽器請求:http://localhost:8080/index.html
  2. 服務器返回401(unauthentication)代碼,並附帶一個包含challenge的頭,格式如下:WWW-Authenticate    Digest realm="Admin All", qop="auth", nonce="1354760194666:4465c7b1921b6d769fd359e5152c453f", opaque="EE9C283E89AFB63E7FF6E2C04C524807"
  3. 瀏 覽器用MD5編碼後的信息添加到請求頭中再次請求1中的資源,如果用戶名是tomcat,密碼是tomcat,則生成的頭信息:Authorization    Digest username="tomcat", realm="Admin All", nonce="1354760194666:4465c7b1921b6d769fd359e5152c453f", uri="/web/index.html", response="8d30e6438636fe21c6045246dd034372", opaque="EE9C283E89AFB63E7FF6E2C04C524807", qop=auth, nc=00000001, cnonce="9201a828891792b9"
  4. 用3中計算的請求頭信息再次請求1中的資源
  5. 服務器用3中相同的算法(base64)驗證用戶密碼合法性
  6. 返回index.html的資源

這裏我們只是討論流程,具體的challenge和digest的生成算法請參考:RFC2617

HttpClient的實現

示例代碼:

HttpHost targetHost = new HttpHost("localhost", 8080);
        
        DefaultHttpClient client = new DefaultHttpClient();
        
        HttpContext context = new BasicHttpContext();
        context.setAttribute(ClientContext.CREDS_PROVIDER, new BasicCredentialsProvider());
        CredentialsProvider provider = (CredentialsProvider)context.getAttribute(ClientContext.CREDS_PROVIDER);
        provider.setCredentials(
                new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                new UsernamePasswordCredentials("tomcat", "admin"));
                
        HttpGet get = new HttpGet("http://localhost:8080/web/Hello");
     HttpResponse response = client.execute(get,context);
        System.out.println(response.getStatusLine());
        HttpEntity entity = response.getEntity();
        String s = EntityUtils.toString(entity);
        System.out.println(s);

 主要類結構圖:

Auth流程圖:

 

 

發佈了20 篇原創文章 · 獲贊 6 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章