How to pass profile username/password as a global variables to Basic Authentication for a REST API

Hello,

I’ve looked in the community forums for an answer to my question and found a similar post at Pass in a global variable username/password into WebService authentication

However it is not clear in this post how to do this. Does anyone have a step by step guide on how to pass profile username/passwords as a global variable to Basic Authentication for a REST API. Similar to how Postman does it - I have three profiles, one for each environment e.g. Dev, Test, Prod. Each profile has a username and password set as each environment has different username/password.

Then I have a GET request set up with Basic Authentication enabled however I’m not sure exactly what needs to go in each of the username/password fields: I have tried the below:

Variables

Authorization

I’ve got a bunch of Postman API’s I’d like to import to Katalon studio - however if it is not possible to do this and I have to manually set the values every time I want to switch environments then I may need to stay with Postman. Appreciate any guidance from anyone that has experienced the same issue.

Thanks!

there is no need to have an exlpanatory guide for this.
you have to put the relevant data in the “http headers” tab
the authorization tab is just a feature doing mostly nothing, other than update the headers for your request
forget about Postman and read more about how RESTfull API’s actually works

This is not a helpful comment.

I’m new to the product and evaluating the product so I am still understanding how it works. Some kindness will go a long way. But thank you for your comment, I will take a look at the HTTP Headers tab.

if you dont spend some time to read the docs of any new toy you intend to use, expect more answers like that.
Long time ago the standard answer was RTFM.

But those days, this imply ‘political correctness’

anyway, this is not an excuse to not read the documentation, no matter if you are experienced or not.
we, as comunity, are here to guide you.
what do you learn is up to you.
i was kind enough?

1 Like

I made a Test Case:

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.testobject.TestObjectProperty
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS

import internal.GlobalVariable

// I have a Test Object "Object Repository/GET localhost" 
// which points "http://localhost/" with no Authorization inforation
TestObject tObj = findTestObject("GET localhost")

// convert it into a RequestObject
RequestObject reqObj = injectAuthenticationHeader((RequestObject)tObj, GlobalVariable.username, GlobalVariable.password)

// send HTTP request
ResponseObject response = WS.sendRequest(reqObj);


RequestObject injectAuthenticationHeader(RequestObject request, String username, String password) {
	// construct a "username:password" string using GlobalVariable
	String credential = "${GlobalVariable.username}:${GlobalVariable.password}"
	println "credential: ${credential}"
	// encode it with Base64
	String encoded = Base64.getEncoder().encodeToString(credential.getBytes())
	println "encoded: ${encoded}"
	List<TestObjectProperty> headers = removeAuthorizationHeader(request.getHttpHeaderProperties())
	headers.add(new TestObjectProperty("Authorization", ConditionType.EQUALS, "Basic ${encoded}"))
	request.setHttpHeaderProperties(headers)
	return request
}

List<TestObjectProperty> removeAuthorizationHeader(List<TestObjectProperty> listTOP) {
	List<TestObjectProperty> list = new ArrayList<TestObjectProperty>()
	for (TestObjectProperty top : listTOP) {
		if (top.getName().equals("Authorization")) {
			; // ignore it
		} else {
			list.add(top)
		}
	}
	return list
}

The Test Object “GET localhost” looked like this:


Please note that the Test Object has no Authorization information set in the GUI.

The test case scripts generates a HTTP header “Authorization: Basic xxxxxx” dynamically refering to the GlobalVariable.username and GlobalVariable.password, and inject the header into the RequestObject.

When I executed this, it showed a message in the console:

2023-02-12 15:59:26.927 INFO  c.k.katalon.core.main.TestCaseExecutor   - --------------------
2023-02-12 15:59:26.930 INFO  c.k.katalon.core.main.TestCaseExecutor   - START Test Cases/GET localhost with Authorization
credential: mockUsername:mockPassword
encoded: bW9ja1VzZXJuYW1lOm1vY2tQYXNzd29yZA==
2023-02-12 15:59:30.076 INFO  c.k.k.core.webservice.common.HarLogger   - HAR: /var/folders/7m/lm7d6nx51kj0kbtnsskz6r3m0000gn/T/Katalon/Test Cases/GET localhost with Authorization/20230212_155923/requests/main/0.har
2023-02-12 15:59:30.257 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/GET localhost with Authorization

When I executed this, my HTTP server printed the request content as follows:

<<<< Request received
{
"method": "GET",
"uri": "/",
"headers": [
    {"Accept-encoding": ["gzip,deflate"]}
    {"Connection": ["Keep-Alive"]},
    {"Host": ["localhost"]},
    {"User-agent": ["Apache-HttpClient/4.5.1 (Java/1.8.0_275)"]},
    {"Authorization": ["Basic bW9ja1VzZXJuYW1lOm1vY2tQYXNzd29yZA=="]},
],
"body": """"""
}

Please find the Authorization header is sent from the Test Case script to the server.

This way the Test Case script could generate a Authorization header dynamically referring to the GlobalVariables which are chosen when you execute the Test Case.

@sedens

This is what you wanted, isn’t it?

I know the code above looks poor.

Perhaps you had better stay there as KS has a few more problems for WS testing:

Another approach to take is to use a parametrized test object.

The user must start to read here also:

In my example, I defined a variable auth in my test object.
I set a default value which corresponds to myuser:mypass encoding.
It can be an empty string, I did that only to confirm it is working properly.
See pic1:

I set this variable in the HTTP header tab as in pic2:

When I send the request directly, in the har file I have:

"name" : "Authorization",
"value" : "Basic bXl1c2VyOm15cGFzcw=="

which matches with the default value i set.

from the test case, i build another string for the anotheruser:anotherpass credentials.
(due to laziness I skipped the GlobalVariable part, this is already shown by @kazurayam )
and I call my test object by maping the variable in the TO with the variable I build in my tescase:

credential = "anotheruser:anotherpass"

//This is the Java fashion example provided by kazu
//encoded = Base64.getEncoder().encodeToString(credential.getBytes())

// This is the 'groovyfied' version
//encoded = Base64.encoder.encodeToString(credential.bytes)

// This is even more more groovyfied
encoded = credential.bytes.encodeBase64().toString()

auth = "Basic ${encoded}"

// we can use also a 'single liner'
//auth = "Basic ${credential.bytes.encodeBase64().toString()}"

WS.sendRequest(findTestObject('Test', [('auth') : auth]))

When I send this, i get the new header in the har file:

"name" : "Authorization",
"value" : "Basic YW5vdGhlcnVzZXI6YW5vdGhlcnBhc3M="

Side note, as a shortcut, the user can store the entire header in the profile variables, it is not rocket science to generate it.
There are plenty online encoders available if a programatic approach is ‘too much’.
So the entire coding part can be skipped and the GlobalVariable defined can be used directly.

But understanding how basic authentication (and any other authentication type) works is a must for a QA engineer.