1. 程式人生 > >《HttpClient官方文件》4.1-4.3 HTTP驗證

《HttpClient官方文件》4.1-4.3 HTTP驗證

原文連結  譯者:edenpan

4 HTTP 驗證

httpClient 對根據HTTP 標準規則制定的許可權驗證方案,以及很多不標準但廣泛使用的驗證方案,比如:NTML和SPNEGO提供完全的支援。

4.1 使用者憑證

任何一個使用者驗證程式需要一系列的憑證資訊用來確認使用者身份。最簡單的使用者憑證就是使用者名稱/密碼。UsernamePasswordCredentials 代表由明文形式的安全主體和密碼組成的一組憑證。這個實現足夠作為標準的根據HTTP標準規範定義的安全驗證規則。

UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());

stdout>

user
pwd

NTCredentials是微軟Windows特有的一個認證方式,包括對使用者名稱/密碼新增另外的Windows的屬性,比如使用者域的名稱。在一個Microsoft Windows network中一個相同的使用者可以屬於多個域並且有不同的憑證。

NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());

stdout>

DOMAIN/user
pwd

4.2 認證方案

AuthScheme 介面代表一個抽象的挑戰-響應(challenge-response)認證方案。一個認證方案希望支援以下功能:

  • 解析和響應目標伺服器傳送的挑戰,迴應對受保護資源的請求。
  • 提供被處理的挑戰的屬性:認證方案型別以及引數,比如這個方案可以適用的領域(如果可行)。
  • 對指定的證書和http請求生成認證字串用來回應實際的認證挑戰。

請注意認證方案也許是有狀態的,涉及一系列challenge-response 的交換。
HttpClient 附帶幾個AuthScheme實現:

  • 基礎(Basic):RFC2617
    中定義的基礎認證方案。這個認證方案是不安全的因為憑證是用明文傳送。儘管如此如果和TSL/SSL加密結合使用 這個認證方案是完全足夠的。
  • 摘要(Digest):RFC2617中定義的摘要認證方案。摘要認證方案明顯的比基礎方案更加安全,並且對於不想使用TLS/SSL加密的應用是一個很好的選擇。

NTLM:NTLM是一個有Microsoft開發並且針對Windows平臺進行了優化的專有驗證方案。它被認為比摘要方案要更加安全。
SPNEGO:SPNEGO(簡單受保護的GSSAPI協商機制)是一個GSSAPI的“偽機制”被用於協商許多可能的真實機制。它最明顯的用途是在Microsoft’s HTTP Negotiate 的認證擴充套件中。這個協商子機制包含了NTLM以及被Active Directory支援的Kerberos。目前HttpClient只支援Kerberos 子機制。
Kerberos:Kerberos認證方案的實現。

4.3 憑證提供者

憑證提供者旨在維護一系列的使用者憑證以及可以在特定的認證範圍內產生使用者憑證。

認證範圍由主機名,埠號,域名和認證方案名組成。當在憑證提供者註冊憑證時,可以使用萬用字元(任意的主機名,埠,域與方案)而不僅僅是一個具體的值。憑證提供者被希望可以在沒有找到完全符合的情況下可以在特定的範圍內查到最相近的值。
HttpClient 可以和任何實際實現了CredentialsProvider介面的憑據提供者合作。預設的CredentialsProvider介面實現為:BasicCredentialsProvider:

CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("somehost", AuthScope.ANY_PORT), 
new UsernamePasswordCredentials("u1", "p1"));
credsProvider.setCredentials(
new AuthScope("somehost", AuthScope.ANY_PORT), 
new UsernamePasswordCredentials("u1", "p1"));
credsProvider.setCredentials(new AuthScope("somehost", 8080), new UsernamePasswordCredentials("u2", "p2"));
credsProvider.setCredentials(
new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"), 
new UsernamePasswordCredentials("u3", "p3"));
System.out.println(credsProvider.getCredentials(new AuthScope("somehost", 80, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("somehost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("otherhost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("otherhost", 8080, null, "ntlm")));

stdout>

[principal: u1]
[principal: u2]
null
[principal: u3]