1

我们尝试在一个 HttpClient(一个会话)中向目标服务器发送多个请求。目标服务器将首先使用摘要身份验证(基于 MD5-sess)对所有请求进行身份验证。结果表明只有第一次访问成功。服务器拒绝以下访问,因为服务器将以后的访问视为重放攻击,因为“nc”值始终为“00000001”。

似乎Android HttpClient硬编码摘要授权标头将“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));
}

}

4

2 回答 2

2

Android 附带 Apache HttpClient 的一个非常过时(测试版前)的分支。自 4.0 ALPHA 以来,HttpClient 的股票版本已经发生了无数次的变化,也在 Digest auth 区域。

您可以做的最好的事情是从 Apache HttpClient 的库存版本中复制 DigestScheme 并将您的应用程序配置为使用副本而不是默认实现。

https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/DigestScheme.java

为此,您必须使用身份验证方案注册表注册自定义 DigestSchemeFactory 实例。

https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/DigestSchemeFactory.java

于 2012-03-23T09:14:22.453 回答
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以使此自动(不要将凭据设置为凭据提供程序)
  • AFAIK 身份验证方案应该是可插入的,因此正确实施摘要身份验证并配置您的客户端以使用它。
  • 使用另一个 HTTP 客户端库。

编辑:由于它在库存版本中已修复,因此还有另一种选择:

另一种选择:

  • 使用jarjar更改Apache HttpClient包名,将其与应用程序一起打包,完全不要使用Android系统。
于 2012-03-23T08:51:30.250 回答