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流程圖:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM