title: NTLM authentication works with curl, but not from Java
body: <p>I try to connect to application which is deployed on Windows Server.
  I uses NTLM. I'm using Ubuntu and Java8.</p>
  
  <p>I'm getting <code>HTTP 401</code> code, but only if I try to connect
  from my Java application. Curl request with exactly the same
  authentication details works ok, I'm getting <code>HTTP 200</code>:</p>
  
  <pre><code>curl -v -L --ntlm -u 'myuser\mydomain:mypass' 'http://myip/api/element/151
  </code></pre>
  
  <p>This is my Java code
  (I simplified it a bit, to include only problem-related stuff):</p>
  
  <pre><code>import javax.ws.rs.client.Client;
  import javax.ws.rs.client.ClientBuilder;
  import javax.ws.rs.client.Entity;
  import javax.ws.rs.client.Invocation;
  import javax.ws.rs.client.WebTarget;
  ...
  import org.apache.http.auth.NTCredentials;
  import org.apache.http.client.CredentialsProvider;
  import org.apache.http.impl.client.BasicCredentialsProvider;
  import org.glassfish.jersey.apache.connector.ApacheClientProperties;
  import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
  ...
  import org.glassfish.jersey.client.ClientConfig;
  import org.glassfish.jersey.client.ClientProperties;
  import org.glassfish.jersey.client.RequestEntityProcessing;
  ...
  
  class MyConnector {
  
      private final Client client;
      ...
  
      protected ClientConfig prepareClientConfig() {
          ClientConfig config = new ClientConfig();
          config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
          config.property(ClientProperties.FOLLOW_REDIRECTS, true);
          config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED);
  
          CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
          credentialsProvider.setCredentials(AuthScope.ANY, new NTCredentials("myuser", "mypassword",
                  "mydomain", "mydomain"));
  
          config.property(ApacheClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
          config.connectorProvider(new ApacheConnectorProvider());
  
          return config;
      }
  
      ...
  
      MyConnector(...) {
  
      ...
      client = ClientBuilder.newClient(prepareClientConfig());
  
      }
  
  
      protected String getDocString(...) throws MyException {
  
          WebTarget target = client.target("http://myipi/api").path("element/151");
  
          Invocation.Builder temp = target.request();
          Response response = target.request().get();
  
          if (response.getStatus() == Status.OK.getStatusCode()) {
              String docString = response.readEntity(String.class);
  
              return docString;
          }
  
          throw new MyException("Couldn't obtain doc. HTTP error code: " + response.getStatus());
      }
  
      ...
  }
  </code></pre>
  
  <p>It takes 5-15 (!) minutes to invoke the <code>getDocString</code> function.
  I also believe that application eats unusually large amount of RAM,
  although no other function is run simultaneously (the program is not parallelised).
  Then I get <code>HTTP 401</code> code.</p>
  
  <p>I had some cases when my Java application worked. The story was:</p>
  
  <ol>
  <li>my application worked without NTLM</li>
  <li>my colleagues added NTLM to their app, I adjusted code, my app got <code>401</code>, my curl request got <code>401</code></li>
  <li>I upgraded from <code>Ubuntu 14 LTS</code> to <code>Ubuntu 16.0.2 LTS</code>, my app got <code>200</code>, curl got <code>200</code></li>
  <li>I gave out the server on which the setup worked (I don't have it any more)</li>
  <li>I set up a new server, again with <code>Ubuntu 16.0.2 LTS</code>, my app got <code>401</code>, curl got <code>200</code></li>
  <li>I upgraded to <code>Ubuntu 17.04</code> (non-LTS), my app got <code>200</code> once, but I cannot
  reproduce it, now exactly the same request gets <code>401</code>, curl gets <code>200</code></li>
  </ol>
  
  <p>I'm aware of this question:
  <a href="https://stackoverflow.com/questions/30075951/how-to-send-ntlm-authenticated-post-request-using-jersey">How to send NTLM authenticated post request using jersey?</a>
  I used the code and it allowed my app to work in combination with server upgrade (at point <code>3.</code>).
  But I don't know how to make it work again.</p>
  
  <p>I used mitmproxy to debug the request, the output looks like this
  (I obscured the <code>Authorization</code>/<code>WWW-Authenticate</code> fields):</p>
  
  <pre><code>Proxy server listening at http://0.0.0.0:8080
  127.0.0.1:39622: clientconnect
  127.0.0.1:39622: request
    -&gt; Request(GET /api/element/151)
  127.0.0.1:39622: serverconnect
    -&gt; myip:80
  127.0.0.1:39622: response
    -&gt; Response(401 Unauthorized, text/html, 1.26k)
  127.0.0.1:39622: GET http://myip/api/element/151
      User-Agent: Jersey/2.26-b03 (Apache HttpClient 4.5.3)
      Host: myip
      Connection: Keep-Alive
      Accept-Encoding: gzip,deflate
   &lt;&lt; 401 Unauthorized 1.26k
      Content-Type: text/html
      Server: Microsoft-IIS/8.5
      WWW-Authenticate: Negotiate
      WWW-Authenticate: NTLM
      X-Powered-By: ASP.NET
      Date: Mon, 29 May 2017 13:38:36 GMT
      Content-Length: 1293
  127.0.0.1:39622: request
    -&gt; Request(GET /api/element/151)
  127.0.0.1:39622: response
    -&gt; Response(401 Unauthorized, text/html; charset=us-ascii, 341b)
  127.0.0.1:39622: GET http://myip/api/element/151
      User-Agent: Jersey/2.26-b03 (Apache HttpClient 4.5.3)
      Host: myip
      Connection: Keep-Alive
      Accept-Encoding: gzip,deflate
      Authorization: NTLM TlRAAA==
   &lt;&lt; 401 Unauthorized 341b
      Content-Type: text/html; charset=us-ascii
      Server: Microsoft-HTTPAPI/2.0
      WWW-Authenticate: NTLM TlRAAABBBBBBAAA==
      Date: Mon, 29 May 2017 13:38:36 GMT
      Content-Length: 341
  127.0.0.1:39622: request
    -&gt; Request(GET /api/element/151)
  127.0.0.1:39622: server communication error: TcpDisconnect('[Errno 104] Connection reset by peer',)
  127.0.0.1:39622: serverdisconnect
    -&gt; myip:80
  127.0.0.1:39622: serverconnect
    -&gt; myip:80
  127.0.0.1:39622: response
    -&gt; Response(401 Unauthorized, text/html, 1.26k)
  127.0.0.1:39622: GET http://myip/api/element/151
      User-Agent: Jersey/2.26-b03 (Apache HttpClient 4.5.3)
      Host: myip
      Connection: Keep-Alive
      Accept-Encoding: gzip,deflate
      Authorization: NTLM TlRAAABBBDDDAAA==
   &lt;&lt; 401 Unauthorized 1.26k
      Content-Type: text/html
      Server: Microsoft-IIS/8.5
      WWW-Authenticate: Negotiate
      WWW-Authenticate: NTLM
      X-Powered-By: ASP.NET
      Date: Mon, 29 May 2017 13:44:35 GMT
      Content-Length: 1293
  127.0.0.1:39622: serverdisconnect
    -&gt; myip:80
  127.0.0.1:39622: clientdisconnect
  </code></pre>
  
  <p>I will be very grateful for any remarks on this.</p>
  
  <p><strong>Update:</strong> I also tried Debian8 and Debian9. The result is the same. I got <code>401</code> ad Debian8, updated to Debian9, got <code>200</code> once and then continuously <code>401</code> (for the exactly same request).</p>