2012-03-23 103 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