【问题标题】:Apache HttpClient 4.1 - Proxy AuthenticationApache HttpClient 4.1 - 代理身份验证
【发布时间】:2011-08-05 20:10:22
【问题描述】:

在使用 Apaches HttpComponent 的 httpclient 时,我一直在尝试从配置的属性中配置代理身份验证的用户和密码,但没有成功。我找到的所有示例都引用了不再可用的方法和类,例如HttpStatesetProxyCredentials

那么,谁能给我一个如何配置代理凭据的示例?

【问题讨论】:

  • 我们说的是 Basic-Auth 还是 NTLM?
  • @nfechner 我正在尽我所能。实际上,最好两者兼而有之。

标签: java proxy apache-httpclient-4.x proxy-authentication


【解决方案1】:

对于任何寻找 4.3 答案的人...它相当新,他们的示例没有使用新的 HttpClientBuilder...所以这就是我在那个版本中实现它的方式:

NTCredentials ntCreds = new NTCredentials(ntUsername, ntPassword,localMachineName, domainName );

CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope(proxyHost,proxyPort), ntCreds );
HttpClientBuilder clientBuilder = HttpClientBuilder.create();

clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost(pxInfo.getProxyURL(), pxInfo.getProxyPort()));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());

CloseableHttpClient client = clientBuilder.build();

【讨论】:

    【解决方案2】:

    对于 Basic-Auth,它看起来像这样:

    DefaultHttpClient httpclient = new DefaultHttpClient();
    httpclient.getCredentialsProvider().setCredentials(
        new AuthScope("PROXY HOST", 8080),
        new UsernamePasswordCredentials("username", "password"));
    
    HttpHost targetHost = new HttpHost("TARGET HOST", 443, "https");
    HttpHost proxy = new HttpHost("PROXY HOST", 8080);
    
    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
    

    AFAIK NTLM 不支持开箱即用。但是您也许可以使用NTCredentials 来管理它,并且可能会重载DefaultProxyAuthenticationHandler

    【讨论】:

    • 代理设置出错或代理服务器宕机时会发生什么情况,如何处理
    • 不是targetHost 变量未使用/不必要吗?
    • 您如何确保代理始终更改 IP 地址以进行多次迭代(比如 100 次)?
    【解决方案3】:

    可以在 4.3+ httpClient 上使用普通的旧用户名和密码来代替 NTLM,如下所示:

    HttpHost proxy = new HttpHost("x.x.com",8080);
    Credentials credentials = new UsernamePasswordCredentials("username","password");
    AuthScope authScope = new AuthScope("x.x.com", 8080);
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(authScope, credentials);
    HttpClient client = HttpClientBuilder.create().setProxy(proxy).setDefaultCredentialsProvider(credsProvider).build();
    HttpResponse response=client.execute(new HttpGet("http://stackoverflow.com/questions/6962047/apache-httpclient-4-1-proxy-authentication"));
    

    【讨论】:

    • 如果我尝试将 UsernamePasswordCredentials 用于需要 NTLM 身份验证的代理,我会收到以下异常:auth.HttpAuthenticator ( HttpAuthenticator.java:207) - NTLM authentication error: Credentials cannot be used for NTLM authentication: org.apache.http.auth.UsernamePasswordCredentials。为了解决这个问题,我改用NTCredentials
    【解决方案4】:

    如何使用 Apache 的 httpclient 设置代理身份验证

    (代理网络上的预授权)

    此答案使用 Apache 的 HttpClient v4.1 及更高版本。

    接受的答案对我不起作用,但我发现了其他方法!

    这里有一些来自 apache 的经过测试和验证的代码,演示了如何通过代理对 HTTP 请求进行身份验证。

    完整文档位于此处:https://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html

    这里还有一个来自 Apache 的优秀示例:https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientProxyAuthentication.java

    • my_username 替换为您的代理用户名
    • 用您的代理密码替换my_password
    • proxy.mycompany.com 替换为您的代理主机
    • 8080 替换为您的代理端口
    • google.com 替换为您希望将 HTTP 请求发送到的站点的主机。
    • /some-path 替换为您要将HTTP 请求发送到的路径。这使用您之前指定的主机站点 (google.com)。

    以下示例将验证username:password@proxy.mycompany.com:8080 并向http://www.google.com/some-path 发送GET 请求,并将打印响应HTTP 代码。

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope("proxy.mycompany", 8080),
                new UsernamePasswordCredentials("my_username", "my_password"));
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider).build();
        try {
            //Replace "google.com" with the target host you want to send the request to
            HttpHost target = new HttpHost("google.com", 80, "http");
            HttpHost proxy = new HttpHost("proxy.mycompany", 8080);
    
            RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .build();
            CloseableHttpResponse response = null;
    
            //Replace "/some-path" with the path you want to send a get request to.
            HttpPost httppost = new HttpPost("/some-path");
            httppost.setConfig(config);
            response = httpclient.execute(target, httppost);
    
            try {
                System.out.println("Return status code is "+response.getStatusLine().getStatusCode());          
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    

    【讨论】:

    • 什么版本的HttpClient?这是一个重要的因素,因为我在以前的版本中看到的东西不适用于 4.1,从 4.3 和 4.5 的答案中可以看出,事情也发生了变化。
    • HttpClients 仅从 4.3 开始存在
    【解决方案5】:

    一个更简单的事情对我来说适用于 NTLM:

    httpclient.getCredentialsProvider().setCredentials(
                        new AuthScope(proxy_host, proxy_port), 
                        new NTCredentials(this.proxy_user, this.proxy_pass, this.proxy_host, this.proxy_domain));
    HttpHost proxy = new HttpHost(this.proxy_host, this.proxy_port, "http");
    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
    

    【讨论】:

      【解决方案6】:

      对于 HttpClient 4.5 和按请求身份验证:

      HttpContext httpContext = new BasicHttpContext();
      AuthState authState = new AuthState();
      
      authState.update(new BasicScheme(), new UsernamePasswordCredentials("userName", "password"));
      httpContext.setAttribute(HttpClientContext.PROXY_AUTH_STATE, authState);
      CloseableHttpResponse httpResponse = httpClient.execute(httpRequest, httpContext);
      

      【讨论】:

      • 如果您不设置代理主机/端口,这将如何工作?
      【解决方案7】:

      如果您必须让您的代码使用 4.1 或想要使用下面的 sn-p,重要的是要知道 httpclient 4.1 不会将身份验证发送到代理。您可能会收到 407“需要代理身份验证”状态代码。我升级到 4.3.3 并且一切正常,尽管 DefaultHttpClient 和 ConnRoutePNames 在此版本中已被弃用。希望这会有所帮助!

      DefaultHttpClient httpclient = new DefaultHttpClient();
      httpclient.getCredentialsProvider().setCredentials(
          new AuthScope("PROXY HOST", 8080),
          new UsernamePasswordCredentials("username", "password"));
      
      HttpHost proxy = new HttpHost("PROXY HOST", 8080);
      
      httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-04
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        • 2018-07-04
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多