未提供有效凭据(机制级别:未提供有效凭据(机制级别:无法找到任何Kerberos tgt))httpclient

时间:2017-04-26 06:53:03

标签: apache-httpclient-4.x

我正在尝试使用http客户端使用ntlm Auth Scheme从服务器下载pdf文件。

但是当我遇到错误时。当我使用带有用户名和密码作为参数的wget时,文件会被下载,但是如果我使用相同的用户名和密码,那么使用java代码的401会失败。我正在使用httpclient 4.2.2

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

以下是使用身份验证下载pdf的代码。

 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();
}
}

有没有人在使用httpclient之前遇到过这种问题? 什么"找不到任何Kerberos tgt"意思? 有人有任何线索吗?

2 个答案:

答案 0 :(得分:0)

以下代码适用于http客户端版本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();

答案 1 :(得分:0)

使用kotlin和httpclient 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()