HttpComponents HttpClient
  1. HttpComponents HttpClient
  2. HTTPCLIENT-1215

http://host and http://host:80 not considered the same for credential matching

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.2.1
    • Fix Version/s: 4.2.2
    • Component/s: HttpClient
    • Labels:
      None

      Description

      the following code (taken from http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html section 4.8 and modified to use a URI) will not add authentication headers to the outgoing http request because the URI string does not explicitely specify the port:

      URI uri = new URI("http://somedomain.com/stuff");
      HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());

      DefaultHttpClient httpclient = new DefaultHttpClient();

      httpclient.getCredentialsProvider().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
      BasicHttpContext localcontext = new BasicHttpContext();
      localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

      HttpGet httpget = new HttpGet(uri);
      for (int i = 0; i < 3; i++)

      { HttpResponse response = httpclient.execute(targetHost, httpget, localcontext); System.err.println(response.getStatusLine()); HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); }

      the root cause for this is in RequestAuthCache.java line 90:

      HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
      if (target.getPort() < 0)

      { SchemeRegistry schemeRegistry = (SchemeRegistry) context.getAttribute( ClientContext.SCHEME_REGISTRY); Scheme scheme = schemeRegistry.getScheme(target); target = new HttpHost(target.getHostName(), scheme.resolvePort(target.getPort()), target.getSchemeName()); }

      AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
      if (target != null && targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) {
      AuthScheme authScheme = authCache.get(target);
      if (authScheme != null)

      { doPreemptiveAuth(target, authScheme, targetState, credsProvider); }

      }

      the target has no port (meaning <0 ), so its recreated with the default http scheme port of 80.
      meanwhile authCache uses the original target host as key, and so authScheme will be null.
      explicitely declaring port 80 in the URI string works around this, but i think this should work by default.

        Issue Links

          Activity

          Oleg Kalnichevski made changes -
          Status Resolved [ 5 ] Closed [ 6 ]
          Oleg Kalnichevski made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Oleg Kalnichevski made changes -
          Link This issue is duplicated by HTTPCLIENT-1242 [ HTTPCLIENT-1242 ]
          Oleg Kalnichevski made changes -
          Field Original Value New Value
          Fix Version/s 4.2.2 [ 12322040 ]
          Radai Rosenblatt created issue -

            People

            • Assignee:
              Unassigned
              Reporter:
              Radai Rosenblatt
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development