title: Apache HttpClient negotiate handle second 401 response
body: <p>I am attempting to access an HTTP service that uses <code>WWW-Authenticate: Negotiate</code> for authentication.</p>
  
  <p>I am using HttpClient using the example from Apache.  I see two requests sent.
  First an initial request with response 401 and headers indicating that <code>WWW-Authenticate: Negotiate</code> is used (expected). Then there is a second request sent with the Authenticate header and token.  The server then responds with another 401 and it's own authenticate token in the header.</p>
  
  <p>When I try making the same request through <code>curl --negotiate</code> I see this same behavior, except curl then sends a third request containing a modified token which finally is successful.</p>
  
  <p>The <a href="http://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/authentication.html#SPNEGO" rel="nofollow noreferrer">Apache tutorial</a> has this to say about it:</p>
  
  <blockquote>
    <p>If more processing is required another HTTP 401 is returned to the
    client with more data in the the WWW-Authenticate header. Client takes
    the info and generates another token passing this back in the
    Authorization header until complete.</p>
  </blockquote>
  
  <p>Which implies that this is a normal thing that can happen but there is no explanation on what to do when it does.</p>
  
  <p>How can I achieve this to authenticate with the HttpClient (or if there is a different way that's easier to do with a different library I open to that as well).  My code, based on the example from HttpClient, is below.</p>
  
  <pre class="lang-java prettyprint-override"><code>public class ClientKerberosAuthentication {
      public static void main(String[] args) throws Exception {
          System.setProperty("java.security.auth.login.config", "login.conf");
          System.setProperty("java.security.krb5.conf", "krb5.conf");
          System.setProperty("sun.security.spnego.debug", "true");
          System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
          DefaultHttpClient httpclient = new DefaultHttpClient();
          try {
              Credentials use_jaas_creds = new Credentials() {
                  public String getPassword() {
                      return null;
                  }
                  public Principal getUserPrincipal() {
                      return null;
                  }
              };
              httpclient.getCredentialsProvider().setCredentials(
                      new AuthScope(null, -1, null),
                      use_jaas_creds);
              HttpUriRequest request =
                      RequestBuilder.post("http://webservice")
                      .setEntity(EntityBuilder.create().setFile(new File("data.txt")).build())
                      .build();
              HttpResponse response = httpclient.execute(request);
              HttpEntity entity = response.getEntity();
              System.out.println("----------------------------------------");
              System.out.println(response.getStatusLine());
              System.out.println("----------------------------------------");
              if (entity != null) {
                  System.out.println(EntityUtils.toString(entity));
              }
              System.out.println("----------------------------------------");
              EntityUtils.consume(entity);
          } finally {
              httpclient.getConnectionManager().shutdown();
          }
      }
  }
  </code></pre>