java Apache HttpClient 4.1.1 NTLM 身份验证不是 SPNEGO

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5746545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:34:23  来源:igfitidea点击:

Apache HttpClient 4.1.1 NTLM authentication not SPNEGO

javantlmapache-httpclient-4.x

提问by Kelly

The problem here is consuming a web resource that has NTLM authentication while using the Apache HttpClient on the client side. The issue I am having is forcing the client to use NTLM authentication. here is a code sapmle.

这里的问题是在客户端使用 Apache HttpClient 时消耗了具有 NTLM 身份验证的 Web 资源。我遇到的问题是强制客户端使用 NTLM 身份验证。这是一个代码示例。

DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getAuthSchemes().register("ntlm",new NTLMSchemeFactory());
NTCredentials creds = new NTCredentials("_myUSer_","_myPass_","_myWorkstation_","_myDomain_");
httpclient.getCredentialsProvider().setCredentials( new AuthScope("serverName",80), creds);
List<String> authpref = new ArrayList<String>();
authpref.add(AuthPolicy.NTLM);
httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);
HttpHost target = new HttpHost("serverName", 80, "http");
HttpGet httpget = new HttpGet("webResource");
HttpContext localContext = new BasicHttpContext();
HttpResponse response = httpclient.execute(target, httpget, localContext);

Here is the error from Java:

这是来自Java的错误:

org.apache.http.client.protocol.RequestTargetAuthentication process
SEVERE: Authentication error: Invalid name provided (Mechanism level: Could not load configuration file C:\WINDOWS\krb5.ini (The system cannot find the file specified))

The web server response is a 401.

Web 服务器响应是一个401.

Any ideas on why the auth policy not being set correctly? Am I missing something in the code?

关于为什么未正确设置身份验证策略的任何想法?我在代码中遗漏了什么吗?

回答by evandongen

I have a similar situation and I suspect that you are setting the wrong parameter: AuthPNames.PROXY_AUTH_PREF. I use AuthPNames.TARGET_AUTH_PREF and all seems to work fine.

我有类似的情况,我怀疑您设置了错误的参数:AuthPNames.PROXY_AUTH_PREF。我使用 AuthPNames.TARGET_AUTH_PREF 并且一切似乎都很好。

回答by Per Hoffmann Olsen

Here is my solution to this Problem: And "evandongen" is right.

这是我对这个问题的解决方案:“evandongen”是对的。

Please note the use of the URIBuilder.

请注意 URIBuilder 的使用。

String username = "uid";
String pwd = "pwd";
String servername = "www.someserver.com";
String workstation = "myworkstation";
String domain = "somedomain";
String relativeurl = "/util/myservice.asmx";

String oldimagePath = "\mypath\image.jpg";

DefaultHttpClient httpclient = new DefaultHttpClient();

try {
    httpclient.getAuthSchemes().register("ntlm",new NTLMSchemeFactory());
    NTCredentials creds = new NTCredentials(username,pwd,workstation,domain);

        httpclient.getCredentialsProvider().setCredentials(new AuthScope(servername,80), creds);

        List authpref = new ArrayList();

        authpref.add(AuthPolicy.NTLM);

        URIBuilder builder = new URIBuilder();
        builder.setScheme("http")
            .setHost(servername)
            .setPath(relativeurl + "/DeleteImage")
            .setParameter("imagePath", oldimagePath);
        URI uri = builder.build();

        httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
        HttpHost target = new HttpHost(servicename, 80, "http");
        HttpGet httpget = new HttpGet(uri);

        HttpContext localContext = new BasicHttpContext();

        HttpResponse response1 = httpclient.execute(target, httpget, localContext);

        BufferedReader reader = new BufferedReader(new InputStreamReader(response1.getEntity().getContent())); 

        String line = reader.readLine(); 
        while (line != null) 
        { 
            System.out.println(line);
            line = reader.readLine(); 
        } 

} catch (Exception e) {
    System.out.println("Exception:"+e.toString());
} finally {
    // End
}

回答by Smitesh

HttpClient did not work for me but the below snippet did. Reference - http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-auth.html

HttpClient 对我不起作用,但下面的代码片段起作用了。参考 - http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-auth.html

    public static String getResponse(String url, String userName, String password) throws IOException {
    Authenticator.setDefault(new Authenticator() {
      @Override
      public PasswordAuthentication getPasswordAuthentication() {
        System.out.println(getRequestingScheme() + " authentication");
        return new PasswordAuthentication(userName, password.toCharArray());
      }
    });

    URL urlRequest = new URL(url);
    HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setRequestMethod("GET");

    StringBuilder response = new StringBuilder();
    InputStream stream = conn.getInputStream();
    BufferedReader in = new BufferedReader(new InputStreamReader(stream));
    String str = "";
    while ((str = in.readLine()) != null) {
      response.append(str);
    }
    in.close();

    return response.toString();
  }

回答by Ian Beaumont

I think this is because of a defect, see here.

我认为这是因为缺陷,请参阅此处