Knowledgebase

HTTP Authentication and Authorization


Background

Scripting examples on how to use different authentication or authorization methods in your load test.


Authentication/Authorization

Examples of various HTTP Authentication methods that can be used with k6. These, plus other examples can be found within the k6 GitHub Repo

Basic authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import encoding from "k6/encoding";
import http from "k6/http";
import { check } from "k6";

const username = "user",
      password = "passwd";

export default function() {
    // Passing username and password as part of URL will authenticate using HTTP Basic Auth
    let res = http.get(`http://${username}:${password}@httpbin.org/basic-auth/${username}/${password}`);

    // Verify response
    check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
        "is correct user": (r) => r.json().user === username
    });

    // Alternatively you can create the header yourself to authenticate using HTTP Basic Auth
    res = http.get(`http://httpbin.org/basic-auth/${username}/${password}`, { headers: { "Authorization": "Basic " + encoding.b64encode(`${username}:${password}`) }});

    // Verify response (checking the echoed data from the httpbin.org basic auth test API endpoint)
    check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
        "is correct user": (r) => r.json().user === username
    });
}

Digest authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import http from "k6/http";
import { check } from "k6";

const username = "user",
      password = "passwd";

export default function() {
    // Passing username and password as part of URL plus the auth option will authenticate using HTTP Digest authentication
    let res = http.get(`http://${username}:${password}@httpbin.org/digest-auth/auth/${username}/${password}`, {auth: "digest"});

    // Verify response (checking the echoed data from the httpbin.org digest auth test API endpoint)
    check(res, {
        "status is 200": (r) => r.status === 200,
        "is authenticated": (r) => r.json().authenticated === true,
        "is correct user": (r) => r.json().user === username
    });
}

NTLM authentication

1
2
3
4
5
6
7
8
9
import http from "k6/http";

const username = "user",
      password = "passwd";

export default function() {
    // Passing username and password as part of URL and then specifying "ntlm" as auth type will do the trick!
    let res = http.get(`http://${username}:${password}@example.com/`, { auth: "ntlm" });
}

AWS Signature v4 authentication

Requests to the AWS APIs requires a special type of auth, called AWS Signature Version 4. k6 doesn’t support this authentication mechanism out of the box, so we’ll have to resort to using a Node.js library called awsv4.js and Browserify (to make it work in k6).

There are a few of steps to make this work:

  1. Make sure you have the necessary prerequisites installed:
  2. Install the awsv4.js library:

    npm install aws4

  3. Run it through browserify:

    browserify node_modules/aws4/aws4.js -s aws4 > aws4.js

  4. Move the aws4.js file to the same folder as your script file and you’ll be able to import it into your test script:

    import aws4 from "./aws4.js"

Here’s an example script to list all the regions available in EC2. Note that the AWS access key and secret key needs to be provided through environment variables.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import http from "k6/http";
import {sleep} from "k6";

// Import browserified AWSv4 signature library
import aws4 from "./aws4.js";

// Get AWS credentials from environment variables
const AWS_CREDS = {
    accessKeyId: __ENV.AWS_ACCESSKEY,
    secretAccessKey: __ENV.AWS_SECRETKEY
};

export default function() {
    // Sign the AWS API request
    const signed = aws4.sign({
            service: 'ec2',
            path: '/?Action=DescribeRegions&Version=2014-06-15'
        }, AWS_CREDS);

    // Make the actual request to the AWS API including the "Authorization" header with the signature
    let res = http.get(`https://${signed.hostname}${signed.path}`, { headers: signed.headers });

    // Print the response
    console.log(res.body);

    sleep(1);
}