0

Trying to connect to a resource which is protected with NTLM authentication. When making a request I get a response 401 unauthenticated, but httpclient doesn't perform NTLM authentication after that.

Added Interceptor to see the communication and it doesn't even attempt to authenticate:

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

No requests made after that.

Any suggestions what can be wrong here?

Here is my code:

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

1 Answer 1

1

The parameters to that NTCredentials constructor should have separate username and domain name.

Parameters:
userName - The user name. This should not include the domain to authenticate with. For example: "user" is correct whereas "DOMAIN\user" is not.
password - The password.
workstation - The workstation the authentication request is originating from. Essentially, the computer name for this machine.
domain - The domain to authenticate within.

Sign up to request clarification or add additional context in comments.

7 Comments

I tried both usernames, with domain and without, the same result
Did you look at the underlying HTTP messages, specifically Authorization and WWW-Authenticate? NTLM auth requires multiple request-responses to setup.
yes, I implemented an interceptor for the http client. I can see that the server responds with header "WWW-Authenticate: Negotiate", but httpclient doesn't perform any requests after it :/
I did a quick test (IIS server, not a domain member, GET using the same client setup you have). For whatever reason if it didn't like the login my interceptor only got 1 request (with correct login it intercepted all 3), but in Wireshark I see all 3 happened... I assume that exact login works when viewed manually in say Internet Explorer? The first and last responses on error also have the same headers and body, so not clear which one HttpClient returns on failure.
For reference, I believe the 2nd response contains the machine name/domain, and the 3rd request contains the login. Its base64 encoded and would need the RFC to fully interpret, but can see if it sent the domain and username you expected with a simple b64 decode.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.