2012-03-23 100 views
1

我們嘗試在一個HttpClient(一個會話)中向目標服務器發送多個請求。目標服務器將首先使用摘要式身份驗證(基於MD5-sess)對所有請求進行身份驗證。結果表明只有首次訪問成功。以下訪問被服務器拒絕,因爲服務器將稍後訪問視爲重播攻擊,因爲「nc」值始終爲「00000001」。Android HttpClient摘要身份驗證授權標頭「nc」硬編碼

看來Android的HttpClient的硬編碼的消化授權頭attirbute 「NC」 到 「00000001」?

當新的請求被髮送時,客戶端有什麼辦法增加這個值?謝謝。

公共類HttpService的{

private static final HttpService instance = new HttpService(); 
private HttpService() { 
    client = getHttpClient(); 
} 

public static HttpService getInstance() { 
    return instance; 
} 

private DefaultHttpClient getHttpClient() { 
    HttpParams params = new BasicHttpParams(); 
    HttpConnectionParams.setStaleCheckingEnabled(params, false); 
    HttpConnectionParams.setConnectionTimeout(params, 15 * 1000); 
    HttpConnectionParams.setSoTimeout(params, 15 * 1000); 
    HttpConnectionParams.setSocketBufferSize(params, 8192); 
    HttpProtocolParams.setUserAgent(params, USER_AGENT); 

    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    Scheme httpScheme = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); 
    Scheme httpsScheme = new Scheme("https", SSLCertificateSocketFactory.getHttpSocketFactory(30 * 1000, null), 443); 
    schemeRegistry.register(httpScheme); 
    schemeRegistry.register(httpsScheme); 
    ClientConnectionManager manager = new ThreadSafeClientConnManager(params, schemeRegistry); 

    //create client 
    DefaultHttpClient httpClient = new DefaultHttpClient(manager, params); 

    httpClient.getCredentialsProvider().setCredentials(new AuthScope(address, port), 
       new UsernamePasswordCredentials(username, password)); 
} 

}

+0

你是如何初始化你的HttpClient的?發佈一些代碼。 – 2012-03-23 08:02:54

+0

初始化非常普遍。我在原始文章中添加示例代碼。謝謝 – lyobwon 2012-03-23 08:31:26

回答

0

看來你是對的。這是Digest.java

//TODO: supply a real nonce-count, currently a server will interprete a repeated request as a replay 
private static final String NC = "00000001"; //nonce-count is always 1 

你應該http://b.android.com文件中的錯誤。你有幾個選擇:

  • 計算摘要並自己創建頭,然後在每個請求上設置它。你可以添加一個HttpRequestInterceptor使這個authomatic(沒有設置憑據,憑據提供)
  • 據我所知的身份驗證方案應該是可插拔的,所以實現正常地消化權威性和配置客戶端來使用它。
  • 使用另一個HTTP客戶端庫。

編輯:由於它是固定在現有版本,還有另外一種選擇:

另一種選擇:

  • 改變使用jarjar Apache的HttpClient的包名,與應用程序包吧,根本不要使用Android系統。
2

Android附帶了Apache HttpClient的過時(pre-BETA)分支。自從4.0 ALPHA以來,HttpClient的股票版本也出現了無數次的變化,也在Digest auth區域。

你能做的最好的事情是到DigestScheme從股市版本的Apache的HttpClient的複製和配置應用程序,而不是使用默認實現複製。

http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java

對於最終你會與身份驗證方案的註冊表註冊自定義DigestSchemeFactory實例。

http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java

+0

它是固定的好東西。另一種選擇:使用jarjar更改Apache HttpClient包名稱,將其與應用程序一起打包,並且完全不使用Android系統。 – 2012-03-23 13:32:54

+0

@尼克萊:可能會重新推出Apache HttpClient 4。1 for Android,它應該是Google提供的完全API兼容的替代版本。 – oleg 2012-03-23 18:28:15

+0

謝謝,很高興知道。它仍然需要使用不同的根包,所以它可能需要更多的工作,然後放入jar中。不過,就我個人而言,它會在我的代碼發佈後立即取代。 – 2012-03-24 16:10:19