HttpClient學習研究---第四章:HTTP authenticationHTTP身份驗證

第四章。HTTP authenticationHTTP身份驗證

HttpClient provides full support for authentication schemes defined by the HTTP standard specification as well as a number of widely used non-standard authentication schemes such asHttpClient提供全力支持身份驗證方案由HTTP標準規範以及許多廣泛使用的非標準的認證方案如 NTLMand SPNEGO.

4.1. 4.1。User credentials用戶憑證

Any process of user authentication requires a set of credentials that can be used to establish user identity. 任何用戶身份驗證的過程需要一系列的證書,可以用來建立用戶標識。In the simplest form user credentials can be just a user name / password pair.在最簡單的形式用戶憑證可以只是一個用戶名/密碼對。 UsernamePasswordCredentialsrepresents a set of credentials consisting of a security principal and a password in clear text. 表示一組憑證組成的一個安全主要和密碼以明文。This implementation is sufficient for standard authentication schemes defined by the HTTP standard specification.這個實現是足夠的對於標準HTTP身份驗證方案中定義的標準規範。

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

stdout >stdout >

user
pwd

NTCredentialsis a Microsoft Windows specific implementation that includes in addition to the user name / password pair a set of additional Windows specific attributes such as the name of the user domain. 是微軟Windows特定的實現,包含除了用戶名/密碼對一組額外的Windows特定的屬性,如用戶域的名稱。In a Microsoft Windows network the same user can belong to multiple domains each with a different set of authorizations.在微軟Windows網絡相同的用戶可以屬於多個域每一組不同的授權。

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

stdout >stdout >

DOMAIN/user
pwd

4.2. 4.2。Authentication schemes身份驗證方案

The這個 AuthSchemeinterface represents an abstract challenge-response oriented authentication scheme. 接口代表一個抽象的質詢-響應導向的身份驗證方案。An authentication scheme is expected to support the following functions:身份驗證方案預計將支持以下功能:

  • Parse and process the challenge sent by the target server in response to request for a protected resource.解析和處理挑戰目標服務器發送的響應請求一個受保護的資源。

  • Provide properties of the processed challenge: the authentication scheme type and its parameters, such the realm this authentication scheme is applicable to, if available提供屬性的處理的挑戰:身份驗證方案類型及其參數,這樣的領域這身份驗證方案適用於,如果可用

  • Generate the authorization string for the given set of credentials and the HTTP request in response to the actual authorization challenge.生成授權字符串給定組憑證和HTTP請求響應實際的授權的挑戰。

Please note that authentication schemes may be stateful involving a series of challenge-response exchanges.請注意,身份驗證方案可能有狀態涉及一系列的質詢-響應交流。

HttpClient ships with severalHttpClient附帶幾個 AuthSchemeimplementations:實現:

  • Basic:基本的:Basic authentication scheme as defined in RFC 2617. 基本身份驗證方案在RFC 2617中定義的。This authentication scheme is insecure, as the credentials are transmitted in clear text. 這種身份驗證方案是不安全的,因爲憑證是明文傳輸的。Despite its insecurity Basic authentication scheme is perfectly adequate if used in combination with the TLS/SSL encryption.儘管它不安全感基本身份驗證方案是完全足夠如果用於結合TLS / SSL加密。

  • Digest.消化。Digest authentication scheme as defined in RFC 2617. 摘要式身份驗證方案在RFC 2617中定義的。Digest authentication scheme is significantly more secure than Basic and can be a good choice for those applications that do not want the overhead of full transport security through TLS/SSL encryption.摘要式身份驗證方案明顯更安全比基本和可以是一個不錯的選擇對於那些不希望應用程序的開銷全部運輸安全通過TLS / SSL加密。

  • NTLM:NTLM:NTLM is a proprietary authentication scheme developed by Microsoft and optimized for Windows platforms. 是一個專有NTLM身份驗證方案由微軟開發和優化了Windows平臺。NTLM is believed to be more secure than Digest.NTLM被認爲是更安全比消化。

  • SPNEGO:SPNEGO: SPNEGO (S年代imple and幾種具體實現和 Pprotected包裝 GSSAPI Negonegotiation Mechanism) is atiation機制)是一個 GSSAPI"pseudo mechanism" that is used to negotiate one of a number of possible real mechanisms. “僞機制”,用於談判的幾種可能的真正機制。SPNEGO's most visible use is in Microsoft'sSPNEGO最可見的使用是在微軟的 HTTP Negotiateauthentication extension. 身份驗證擴展。The negotiable sub-mechanisms include NTLM and Kerberos supported by Active Directory. 子機制的可轉讓包括NTLM和Kerberos支持活動目錄。At present HttpClient only supports the Kerberos sub-mechanism.目前國內外HttpClient只支持Kerberos。

  • Kerberos:Kerberos:Kerberos authentication implementation.Kerberos身份驗證實現。

4.3. 4.3。Credentials provider憑證提供者

Credentials providers are intended to maintain a set of user credentials and to be able to produce user credentials for a particular authentication scope. 證書提供商旨在維護一組用戶憑證和能夠產生用戶憑證爲一個特定的認證範圍。Authentication scope consists of a host name, a port number, a realm name and an authentication scheme name. 認證範圍由一個主機名、端口號、一個域名和一個身份驗證方案的名字。When registering credentials with the credentials provider one can provide a wild card (any host, any port, any realm, any scheme) instead of a concrete attribute value. 當註冊憑證與憑證提供者一個可以提供一個通配符(任何主機,任何港口,任何領域,任何計劃),而不是一個具體的屬性值。The credentials provider is then expected to be able to find the closest match for a particular scope if the direct match cannot be found.憑據提供程序是那麼期望能夠找到最接近的匹配特定範圍如果直接匹配不能發現。

HttpClient can work with any physical representation of a credentials provider that implements theHttpClient可以處理任何物理表示的一個憑據提供程序實現 CredentialsProviderinterface. 接口。The default默認 CredentialsProviderimplementation called實現稱爲 BasicCredentialsProvideris a simple implementation backed by a是一個簡單的實現支持嗎 java.util.HashMap.

CredentialsProvider credsProvider = new BasicCredentialsProvider();
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 >stdout >

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

4.4. 4.4。HTTP authentication and execution contextHTTP身份驗證和執行上下文

HttpClient relies on theHttpClient依賴於 AuthStateclass to keep track of detailed information about the state of the authentication process. 類來跟蹤詳細信息驗證過程的狀態。HttpClient creates two instances ofHttpClient創建的兩個實例 AuthStatein the course of HTTP request execution: one for target host authentication and another one for proxy authentication. 在HTTP請求的過程執行:一個用於目標主機認證,另一個用於代理身份驗證。In case the target server or the proxy require user authentication the respective如果目標服務器或代理需要用戶身份驗證各自的 AuthScopeinstance will be populated with the實例將被填充 AuthScope, AuthSchemeand Crednetialsused during the authentication process. 認證過程中使用。The這個 AuthStatecan be examined in order to find out what kind of authentication was requested, whether a matching可以檢查以便找出什麼樣的認證要求,是否匹配 AuthSchemeimplementation was found and whether the credentials provider managed to find user credentials for the given authentication scope.實現被發現和憑證是否提供者成功找到給定的用戶憑據的身份驗證範圍。

In the course of HTTP request execution HttpClient adds the following authentication related objects to the execution context:HTTP請求的過程中執行添加以下身份驗證相關HttpClient對象來執行上下文:

  • Lookupinstance representing the actual authentication scheme registry. 實例代表實際的驗證方案註冊表。The value of this attribute set in the local context takes precedence over the default one.這個屬性的值設置在本地上下文優先於默認的一個。

  • CredentialsProviderinstance representing the actual credentials provider. 實例代表實際的憑證提供者。The value of this attribute set in the local context takes precedence over the default one.這個屬性的值設置在本地上下文優先於默認的一個。

  • AuthStateinstance representing the actual target authentication state. 實例代表實際的目標身份驗證狀態。The value of this attribute set in the local context takes precedence over the default one.這個屬性的值設置在本地上下文優先於默認的一個。

  • AuthStateinstance representing the actual proxy authentication state. 實例代表實際的代理身份驗證狀態。The value of this attribute set in the local context takes precedence over the default one.這個屬性的值設置在本地上下文優先於默認的一個。

  • AuthCacheinstance representing the actual authentication data cache. 實例代表實際的驗證數據緩存。The value of this attribute set in the local context takes precedence over the default one.這個屬性的值設置在本地上下文優先於默認的一個。

The local當地 HttpContextobject can be used to customize the HTTP authentication context prior to request execution, or to examine its state after the request has been executed:對象可以用來定製HTTP身份驗證上下文請求執行之前,或之後檢查其狀態在請求執行:

CloseableHttpClient httpclient = <...>

CredentialsProvider credsProvider = <...>
Lookup<AuthSchemeProvider> authRegistry = <...>
AuthCache authCache = <...>

HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthSchemeRegistry(authRegistry);
context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("http://somehost/");
CloseableHttpResponse response1 = httpclient.execute(httpget, context);
<...>

AuthState proxyAuthState = context.getProxyAuthState();
System.out.println("Proxy auth state: " + proxyAuthState.getState());
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
AuthState targetAuthState = context.getTargetAuthState();
System.out.println("Target auth state: " + targetAuthState.getState());
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());

4.5. 4.5。Caching of authentication data緩存的認證數據

As of version 4.1 HttpClient automatically caches information about hosts it has successfully authenticated with. 自版本4.1 HttpClient自���緩存主機信息經過用它已經成功。Please note that one must use the same execution context to execute logically related requests in order for cached authentication data to propagate from one request to another. 請注意,必須使用相同的執行上下文執行邏輯上相關的請求爲緩存的身份驗證數據傳播從一個請求到另一個。Authentication data will be lost as soon as the execution context goes out of scope.身份驗證數據將丟失一旦執行上下文超出範圍。

4.6. 4.6。Preemptive authentication先發制人的身份驗證

HttpClient does not support preemptive authentication out of the box, because if misused or used incorrectly the preemptive authentication can lead to significant security issues, such as sending user credentials in clear text to an unauthorized third party. HttpClient不支持先佔式認證的盒子,因爲如果誤用或使用不當的先發制人的認證可以導致嚴重的安全問題,比如用戶憑證以明文發送到一個未經授權的第三方。Therefore, users are expected to evaluate potential benefits of preemptive authentication versus security risks in the context of their specific application environment.因此,用戶將評估的潛在好處先佔式認證與安全風險在他們的特定應用程序的上下文環境。

Nonethess one can configure HttpClient to authenticate preemptively by prepopulating the authentication data cache.可配置Nonethess HttpClient驗證通過prepopulating先發制人的身份驗證數據緩存。

CloseableHttpClient httpclient = <...>

HttpHost targetHost = new HttpHost("localhost", 80, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
        new AuthScope(targetHost.getHostName(), targetHost.getPort()),
        new UsernamePasswordCredentials("username", "password"));

// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);

// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);

HttpGet httpget = new HttpGet("/");
for (int i = 0; i < 3; i++) {
    CloseableHttpResponse response = httpclient.execute(
            targetHost, httpget, context);
    try {
        HttpEntity entity = response.getEntity();

    } finally {
        response.close();
    }
}

4.7. 4.7。NTLM AuthenticationNTLM認證

As of version 4.1 HttpClient provides full support for NTLMv1, NTLMv2, and NTLM2 Session authentication out of the box. 自版本4.1提供全力支持NTLMv1 HttpClient,NTLMv2,NTLM2會話驗證出箱。One can still continue using an external人們仍然可以繼續使用一個外部的 NTLMengine such as引擎如JCIFSJCIFSlibrary developed by the圖書館開發的Sambasambaproject as a part of their Windows interoperability suite of programs.項目作爲她們的Windows互操作性程序套件。

4.7.1. 4.7.1。NTLM connection persistenceNTLM連接持久性

The這個 NTLMauthentication scheme is significantly more expensive in terms of computational overhead and performance impact than the standard身份驗證方案是更昂貴的計算開銷和性能方面比標準的影響 Basicand Digestschemes. 方案。This is likely to be one of the main reasons why Microsoft chose to make這可能是一個主要的原因爲什麼微軟選擇了把 NTLMauthentication scheme stateful. 身份驗證方案狀態。That is, once authenticated, the user identity is associated with that connection for its entire life span. 也就是說,一旦用戶通過身份認證,身份是與之相關的連接對其整個生命週期。The stateful nature of有狀態的本質 NTLMconnections makes connection persistence more complex, as for the obvious reason persistent連接使連接持久性更復雜的,因爲很明顯的原因持久 NTLMconnections may not be re-used by users with a different user identity. 連接可能不被重用,用戶用一個不同的用戶身份。The standard connection managers shipped with HttpClient are fully capable of managing stateful connections. 附帶的標準連接經理HttpClient完全有能力管理有狀態連接。However, it is critically important that logically related requests within the same session use the same execution context in order to make them aware of the current user identity. 然而,它是非常重要的,邏輯上相關的請求在同一會話中使用相同的執行上下文爲了使他們意識到當前用戶身份。Otherwise, HttpClient will end up creating a new HTTP connection for each HTTP request against否則,HttpClient最終將創建一個新的HTTP連接每個HTTP請求的反對 NTLMprotected resources. 受保護的資源。For detailed discussion on stateful HTTP connections please refer to詳細的討論有狀態的HTTP連接請參考thissection.部分。

As作爲 NTLMconnections are stateful it is generally recommended to trigger連接���態通常建議來觸發 NTLMauthentication using a relatively cheap method, such as身份驗證使用相對便宜的方法,如 GETor HEAD, and re-use the same connection to execute more expensive methods, especially those enclose a request entity, such as,和重用相同的連接來執行更多的昂貴的方法,尤其是那些附上一個請求的實體,如 POSTor PUT.

CloseableHttpClient httpclient = <...>

CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
        new NTCredentials("user", "pwd", "myworkstation", "microsoft.com"));

HttpHost target = new HttpHost("www.microsoft.com", 80, "http");

// Make sure the same context is used to execute logically related requests
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);

// Execute a cheap method first. This will trigger NTLM authentication
HttpGet httpget = new HttpGet("/ntlm-protected/info");
CloseableHttpResponse response1 = httpclient.execute(target, httpget, context);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}

// Execute an expensive method next reusing the same context (and connection)
HttpPost httppost = new HttpPost("/ntlm-protected/form");
httppost.setEntity(new StringEntity("lots and lots of data"));
CloseableHttpResponse response2 = httpclient.execute(target, httppost, context);
try {
    HttpEntity entity2 = response2.getEntity();
} finally {
    response2.close();
}

4.8.4.8。SPNEGO/Kerberos Authentication/ Kerberos身份驗證

The這個 SPNEGO (S年代imple and幾種具體實現和 Pprotected包裝 GSSAPI Negonegotiation Mechanism) is designed to allow for authentication to services when neither end knows what the other can use/provide. tiation機制)被設計成允許身份認證服務結束時既不知道其他可以使用/提供。It is most commonly used to do Kerberos authentication. 它是最常用來做Kerberos身份驗證。It can wrap other mechanisms, however the current version in HttpClient is designed solely with Kerberos in mind.它可以用其他機制,然而當前版本在設計使用Kerberos HttpClient完全記住。

4.8.1.4 8 1。SPNEGOsupport in HttpClient支持HttpClient

The這個 SPNEGOauthentication scheme is compatible with Sun Java versions 1.5 and up. 身份驗證方案兼容Sun Java版本1.5和起來。However the use of Java >= 1.6 is strongly recommended as it supports然而使用Java > = 1.6是強烈推薦的,因爲它支持 SPNEGOauthentication more completely.身份驗證更完全。

The Sun JRE provides the supporting classes to do nearly all the Kerberos and太陽JRE提供了支持類做幾乎所有的Kerberos和 SPNEGOtoken handling. 令牌處理。This means that a lot of the setup is for the GSS classes. 這意味着大量的設置是爲GSS類。The這個 SPNegoSchemeis a simple class to handle marshalling the tokens and reading and writing the correct headers.是一個簡單的類處理編組的令牌和讀寫正確的標題。

The best way to start is to grab the最好的開始方式是抓起 KerberosHttpClient.javafile in examples and try and get it to work. 文件的例子,試着讓它工作。There are a lot of issues that can happen but if lucky it'll work without too much of a problem. 有很多問題會發生但如果幸運會工作沒有太大的問題。It should also provide some output to debug with.它還應該提供一些輸出調試用。

In Windows it should default to using the logged in credentials; this can be overridden by using 'kinit' e.g.在Windows中它應該默認爲使用登錄憑證;這也能被使用的kinit”如。 $JAVA_HOME\bin\kinit [email protected], which is very helpful for testing and debugging issues. ,這是非常有用的對於測試和調試問題。Remove the cache file created by kinit to revert back to the windows Kerberos cache.刪除緩存文件由kinit恢復到windows Kerberos緩存。

Make sure to list確保列表 domain_realmsin the krb5.conffile. 文件。This is a major source of problems.這是一個主要的問題。

4.8.2. 4 8 2。GSS/Java Kerberos SetupGSS / Java Kerberos設置

This documentation assumes you are using Windows but much of the information applies to Unix as well.本文檔假設您使用的是Windows,但大部分的信息適用於Unix爲好。

The這個 org.ietf.jgssclasses have lots of possible configuration parameters, mainly in the類有很多可能的配置參數,主要是在 krb5.conf/krb5.inifile. 文件。Some more info on the format at一些更多的信息的格式http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.htmlhttp://web.mit.edu/kerberos/krb5 - 1.4 - / - - - - - - - admin/krb5.conf.html krb5 1.4.1/doc/krb5.

4.8.3.4 8 3。login.conffile文件

The following configuration is a basic setup that works in Windows XP against both下面的配置是一個基本的設置,在Windows XP對抗雙方的工作 IISand JBoss Negotiationmodules.模塊。

The system property系統屬性 java.security.auth.login.configcan be used to point at the可以用來指向 login.conffile.文件。

login.confcontent may look like the following:內容可能看起來如下:

com.sun.security.jgss.login {
  com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};

com.sun.security.jgss.initiate {
  com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};

com.sun.security.jgss.accept {
  com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
};

4.8.4.4 8 4。krb5.conf / krb5.inifile文件

If unspecified, the system default will be used. ��果沒有指定,默認將使用的系統。Override if needed by setting the system property如果需要覆蓋通過設置系統屬性 java.security.krb5.confto point to a custom指向一個定製 krb5.conffile.文件。

krb5.confcontent may look like the following:內容可能看起來如下:

[libdefaults]
    default_realm = AD.EXAMPLE.NET
    udp_preference_limit = 1
[realms]
    AD.EXAMPLE.NET = {
        kdc = KDC.AD.EXAMPLE.NET
    }
[domain_realms]
.ad.example.net=AD.EXAMPLE.NET
ad.example.net=AD.EXAMPLE.NET

4.8.5. 4 8 5。Windows Specific configurationWindows特定的配置

To allow Windows to use the current user's tickets, the system property允許Windows使用當前用戶的門票,系統屬性 javax.security.auth.useSubjectCredsOnlymust be set to必須設置爲 falseand the Windows registry key和Windows的註冊表鍵 allowtgtsessionkeyshould be added and set correctly to allow session keys to be sent in the Kerberos Ticket-Granting Ticket.應該添加和正確設置允許發送會話密鑰在Kerberos票據授予票。

On the Windows Server 2003 and Windows 2000 SP4, here is the required registry setting:在Windows Server 2003和Windows 2000 SP4,這裏是必需的註冊表設置:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01

            

Here is the location of the registry setting on Windows XP SP2:下面是註冊表設置的位置在Windows XP SP2:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章