Unauthorized with NTLM auth


I am trying to authorize with NTLM auth, but can’t seem to get t right. I can authorize with Postman and NTLM auth there, but my script still get 401s…

Here is a simple version of the script:

import http from "k6/http";
import { check, sleep } from "k6";

export default function() {

    let res = http.get("http://username:password@URL", {auth: "ntlm"});
    console.log("Status code: " + res.status);
    check(res, {
        "status was 200": (r) => r.status == 200

Is it any way to debug the NTML part? How do I know that it actually tried to authorized with NTLM?
Request output:

User-Agent: k6/0.25.0 (https://k6.io/)
Accept-Encoding: gzip

Here’s the response:

HTTP/1.1 401 Unauthorized
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-1
Date: Wed, 16 Oct 2019 14:32:43 GMT
Server: Apache/2.4.37 (Win64) OpenSSL/1.0.2q-fips mod_jk/1.2.46
Www-Authenticate: Negotiate
Www-Authenticate: NTLM

Access Denied.

If removing the NTLM auth from Postman, the response is like the one from the script. If I type wrong password, I get a set-cookie in the response… It seems to me that k6 don’t try the NTLM auth.

@niklasbae, which k6 version are you using? Your script seems correct, and k6 should handle NTLM authentication…

I used the windows installer, so I guess latest and greatest:

$ k6 version
k6 v0.25.0

Hmm the latest is v0.25.1: Release v0.25.1 · grafana/k6 · GitHub

Even though this point release didn’t directly touch the NTLM auth handling, there were still some significant changes in the HTTP code, so can you update to that version and see if the problem persists?

I assume you got the HTTP request and response with the --http-debug k6 flag - v0.25.1 fixes some things with it, so it will be helpful to upgrade and share the output of that k6 version.

Sure, can try. You should update the URL on the download page to the one you provide on GitHub:)

I see that if I check this tag, I get the similar response in Postman (it needs to be unchecked):

Is it any functionality for this in k6?

I in the Postman console I see that when checked, I get a 401 and Postman runs 1 request. When unchecked, Postman runs 3 request, resulting in successful auth.

You should update the URL on the download page to the one you provide on GitHub:)

Can you point where the link to v0.25.0 package is? We need to fix it, but I can’t find it, I only find links to https://dl.bintray.com/loadimpact/windows/k6-v0.25.1-amd64.msi (in GitHub - grafana/k6: A modern load testing tool, using Go and JavaScript - https://k6.io) and to https://dl.bintray.com/loadimpact/windows/k6-latest-amd64.msi (which is v0.25.1 again).

Is it any functionality for this in k6?
I in the Postman console I see that when checked, I get a 401 and Postman runs 1 request. When unchecked, Postman runs 3 request, resulting in successful auth.

There’s no such option in k6. I’m not sure about the precise postman NTLM implementation, but k6 should do something like the 3 requests postman would do when the checkbox is unchecked:

  • k6 sends a request to the remote server
  • the remote server sends 401 and some values needed in the response
  • k6 uses these values to construct the proper NTLM Authorization header and re-sends the authenticated request

So, can you run your test with k6 v0.25.1 and the --http-debug flag and post the results here?

The v0.25.0 package is found here: Installation

I see from the repo that the NTLM support should do thing correctly…

It seems like we have some policy issues which make me unable to install the latest version these days, but I’ll do as soon as the permissions are updated. Meanwhile, can we try to figure something out with the information we currently have?

Thanks for pointing out the issue, I fixed the docs :man_facepalming: .

Regarding NTLM, the PR you linked is old, but yeah, k6 should handle NTLM auth correctly. We now even use a Microsoft library ( GitHub - Azure/go-ntlmssp: NTLM/Negotiate authentication over HTTP) to do the authentication… But I’m not sure how to proceed without having accurate debug information with your specific case :confused:

Sorry for the delay, but I’ve just installed the latest version.

The output now is more useful, and it seems like the cookie from the CHALLENGE request (the second of the three requests) is not set for the third and final.

Another thing I notice is that the Authorization header has Negotiate instead of NTLM as in Postman, but the handshake seems to work nevertheless.

Ah, then this definitely seems like a bug in k6… :disappointed: I’ve created a new GitHub issue to track it: Cookies not saved during NTLM auth negotiation · Issue #1210 · grafana/k6 · GitHub Thanks for helping us diagnose this and sorry for the inconvenience!

Sure, Im glad to help!

Is there any way to control the NTML flow for me at this stage, or is the second/third request not configurable?

Unfortunately, there’s no way to control the NTLM auth flow :disappointed: You could try to re-implement the NTLM authentication in a pure JS wrapper around the plain k6 HTTP request making methods, but it’d be prohibitively difficult and CPU-inefficient :disappointed: I see that there are node libraries like https://github.com/SamDecrock/node-http-ntlm/blob/master/ntlm.js for the most complicated bits, but converting them with something like browserify would be quite inefficient…

Aha, I guess I’ll wait for an update then. How long does this type of bugfix usually take?:slight_smile:

Difficult to say, sorry. I’ve tagged it for v0.27.0 for now, and we’re aiming to release v0.26.0 in a week… The complication in this case is that from a cursory look, fixing this bug seems to require a substantial refactoring in how we handle NTLM (and maybe digest) authentication, but I might be mistaken.

I see. It would have been awesome if you managed to push it with v0.26.0, because I really need it for an important test we’re running soon…

I have done some more debuging, and I see that the third request dont actually send the value in the set-cookie in Postman either. The major difference is whats sent in the third request:

Other differences:
NTLM vs Negotiate in the Authorization header
The base64 Authorization header is not equal in the first request
The third request has a much shorter Authorization header in Postman
The third request sends the cookie SSOCHALLENGE=NTC_CHALLENGE_DONE; SSOSESSION={session} in Postman

Do you have any more information regarding this? I see that there’s no activity on the bug in GitHub…

This looks a lot like a bug in the library we used which is from … .azure … so Microsoft. But we can’t confirm or deny it as we need a server to test with and as I commented I had no luck finding something public or running IIS.

Given what you have provided some additional specific configuration will be needed to replicate your case and given that … NTLM is not exactly the most used technology for now we are concentrating on releasing the next version of k6 and pushing forward other features and bug fixes.

At some point I am likely to try again to get an ntlm server working, but it’s unlikely to be in the next couple of months. If you can provide at least a testing environment or would like to try and fix it - we will try to help you, but otherwise it will probably be some months before we get a second try at figuring it out, sorry :frowning_face:

@niklasbae can you try v0.22.1 which uses another library for NTLM to see if reverting to it will help …