【问题标题】:java - HttpClient doesn't authenticate with NTLMjava - HttpClient 不使用 NTLM 进行身份验证
【发布时间】:2018-09-26 07:03:22
【问题描述】:

尝试连接到受 NTLM 身份验证保护的资源。 发出请求时,我收到未经身份验证的响应 401,但之后 httpclient 不执行 NTLM 身份验证。

添加了拦截器来查看通信,它甚至不尝试进行身份验证:

Request:
POST/NAV/xxxxxxxxx
Content-type: text/xml; charset=utf-8
SOAPAction:
Content-Length: 359
Host: xxx.local:7051
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.4 (Java/1.8.0_181)
Accept-Encoding: gzip,deflate


Response:
Unauthorized
Content-Length: 0
Server: Microsoft-HTTPAPI/2.0
WWW-Authenticate: Negotiate
Date: Wed, 26 Sep 2018 10:37:56 GMT

之后没有请求。

有什么建议吗?

这是我的代码:

NTCredentials credentials = new NTCredentials("testuser", "pass1", null, "stt.local");
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY, credentials);

        ArrayList<String> authPrefs = new ArrayList<String>();
        authPrefs.add(AuthSchemes.NTLM);


        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM))
                .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
                .build();


        HttpClient client = HttpClientBuilder.
                create().
                setDefaultCredentialsProvider(credsProvider).
                setDefaultRequestConfig(requestConfig).
                addInterceptorLast(new LoggingRequestInterceptor()).
                addInterceptorLast(new LoggingResponseInterceptor()).
                build();



        HttpPost post = new HttpPost(endpoint); //Provide Request URL


        try {

            StringEntity input = new StringEntity(bodyAsString);
            input.setContentType("text/xml; charset=utf-8");
            post.setEntity(input);

            post.setHeader("Content-type", "text/xml; charset=utf-8");
            post.setHeader("SOAPAction", ""); //Provide Soap action


            org.apache.http.HttpResponse response = client.execute(post);
    }

【问题讨论】:

    标签: java windows-authentication apache-commons-httpclient


    【解决方案1】:

    NTCredentials 构造函数的参数应该有单独的用户名和域名。

    参数:
    userName - 用户名。这不应包括要进行身份验证的域。例如:“user”是正确的,而“DOMAIN\user”不是。
    密码 - 密码。
    工作站 - 身份验证请求源自的工作站。 本质上,这台机器的计算机名称。
    domain - 要在其中进行身份验证的域。

    【讨论】:

    • 我尝试了两个用户名,有域和没有域,结果相同
    • 您是否查看了底层 HTTP 消息,特别是 AuthorizationWWW-Authenticate? NTLM 身份验证需要多个请求响应才能设置。
    • 是的,我为 http 客户端实现了一个拦截器。我可以看到服务器以标题“WWW-Authenticate:Negotiate”响应,但httpclient在它之后不执行任何请求:/
    • 我做了一个快速测试(IIS 服务器,不是域成员,使用与您相同的客户端设置进行 GET)。无论出于何种原因,如果它不喜欢登录,我的拦截器只收到 1 个请求(正确登录,它拦截了所有 3 个请求),但在 Wireshark 中我看到所有 3 个都发生了......我假设在说 Internet 中手动查看时确切的登录有效探险家?错误的第一个和最后一个响应也具有相同的标头和正文,因此不清楚哪个 HttpClient 在失败时返回。
    • 作为参考,我相信第二个响应包含机器名称/域,第三个请求包含登录。它的 base64 编码并且需要 RFC 来完全解释,但可以通过简单的 b64 解码查看它是否发送了您期望的域和用户名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多