7

I am trying to download pdf file from server using http client using ntlm Auth Scheme.

but I am getting below error when. The file is getting downloaded when I used wget with username and password as parameters but if I use same username and password it fails with 401 using java code. I am using httpclient 4.2.2

Authentication error: No valid credentials provided (Mechanism level: No valid credentials provided 
(Mechanism level: Failed to find any Kerberos tgt))

Below is my code to download pdf using auth.

 public ByteArrayOutputStream getFile1(String resourceURL) throws CRMBusinessException {
DefaultHttpClient httpclient = new DefaultHttpClient();
ByteArrayOutputStream tmpOut = null;
try {
  ICRMConfigCache cache = CacheUtil.getCRMConfigCache();
  String host = cache.getConfigValue(ConfigEnum.DOCUMENT_SOURCE_HOST_NAME.toString());
  String user = cache.getConfigValue(ConfigEnum.HTTP_USER_NAME.toString());
  String password = cache.getConfigValue(ConfigEnum.HTTP_PASSWORD.toString());
  String workstation = cache.getConfigValue(ConfigEnum.CLIENT_HOST_NAME.toString());

  // Prerequisites
  PreCondition.checkEmptyString(resourceURL, "'resourceURL' cannot be empty or null");
  PreCondition.checkEmptyString(host, ConfigEnum.DOCUMENT_SOURCE_HOST_NAME + " property is not set in database");
  PreCondition.checkEmptyString(user, ConfigEnum.HTTP_USER_NAME + " property is not set in database");
  PreCondition.checkEmptyString(password, ConfigEnum.HTTP_PASSWORD + " property is not set in database");
  PreCondition.checkEmptyString(workstation, ConfigEnum.CLIENT_HOST_NAME + " property is not set in database");

  // NTLM authentication across all hosts and ports
  httpclient.getCredentialsProvider().setCredentials(
      new AuthScope(host, AuthScope.ANY_PORT, AuthScope.ANY_HOST),
      new NTCredentials(user, password, workstation, MY_DOMAIN));

  httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());

  // Execute the GET request
  HttpGet httpget = new HttpGet(resourceURL);

  HttpResponse httpresponse = httpclient.execute(httpget);
  if (httpresponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
tmpOut = new ByteArrayOutputStream();
    InputStream in = httpresponse.getEntity().getContent();
    byte[] buf = new byte[1024];
    int len;
    while (true) {
      len = in.read(buf);
      if (len == -1) {
        break;
      }
      tmpOut.write(buf, 0, len);
    }
    tmpOut.close();
  }

  aLog.debug( "IntranetFileDownloaderImpl - getFile - End - " + resourceURL);
  return tmpOut;
} catch (Exception e) {
  aLog.error("IntranetFileDownloaderImpl - getFile - Error while downloading " + resourceURL + "[" + e.getMessage() + "]", e);
  throw new CRMBusinessException(e);
} finally {
  httpclient.getConnectionManager().shutdown();
}
}

Has anyone faced this kind of issue before while using httpclient? What does "Failed to find any Kerberos tgt" mean? Anybody has any clue on it?

Jigar Naik
  • 1,946
  • 5
  • 29
  • 60

2 Answers2

1

Using kotlin and httpclient version 4.5.8:

    val credentialsProvider = BasicCredentialsProvider().apply {
        setCredentials(
                AuthScope(AuthScope.ANY),
                NTCredentials(user, password, null, domain))
    }

    val requestConfig = RequestConfig.custom().setTargetPreferredAuthSchemes(listOf(AuthSchemes.NTLM)).build()

    return HttpClients.custom()
            .setDefaultCredentialsProvider(credentialsProvider)
            .setDefaultRequestConfig(requestConfig)
            .build()
Tiago Peixoto
  • 335
  • 3
  • 11
0

Below code worked for me with http client version 4.2.2.

DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpGet httpget = new HttpGet("url"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new NTCredentials("username", "pwd", "", "domain"));
                List<String> authtypes = new ArrayList<String>();
        authtypes.add(AuthPolicy.NTLM);      
        httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF,authtypes);

    localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);
    HttpResponse response = httpclient.execute(httpget, localContext);
    HttpEntity entity=response.getEntity();
Jigar Naik
  • 1,946
  • 5
  • 29
  • 60
  • What is the meaning of the two last args of NTCredentials constructor: workstation and domani? – Marcin Sanecki Nov 17 '17 at 21:45
  • This did not work for me for 4.2.2 or 4.5.6 and Java 8. I got HTTP/1.1 401 Unauthorized [Content-Length: 58, Content-Type: text/html, Server: Microsoft-IIS/8.5, WWW-Authenticate: Negotiate, WWW-Authenticate: NTLM, Access-Control-Allow-Origin: *, X-Powered-By: ASP.NET, Date: Fri, 03 Aug 2018 20:38:09 GMT] – John Aug 03 '18 at 20:42
  • ...or maybe it did. I was using the wrong username (doh!). I noticed trying the method described here: https://stackoverflow.com/questions/5917356/httpclient-4-1-1-returns-401-when-authenticating-with-ntlm-browsers-work-fine/20047880#20047880][1] – John Aug 03 '18 at 21:28