I am new to Katalon (second day using it) and new to Groovy (second day using it as well). I am both learning Katalon as well as evaluating it for the company (if it does what we want, I’ll recommend purchasing a service contract).
I am developing some SOAP API’s that requires secure authentication. The initial request is a login containing UID, device ID, and a password and the response is a token that is used for a subsequent API request. For the subsequent request, the token is sent back to the API and it is compared to the token that it sent to the client. If they match, then the request is processed, otherwise it is not. This is the typical tokenized M2M authorization scheme. FWIW, I know these commands work as I can manually test them through the interface provided by our WebLogic server, but I want to automate the testing.
The problem I’m having is that I can’t figure out how to get the session ID from the response header after login and use it for the next API test. When I try to read the header fields from the login request, I get a null value returned. The HAR file shows that the session ID (and the rest of the HTTP header data) is being received by by Katalon, but I can’t seem to be able to retrieve the data I need. Here’s the code I have so far. Note that both tests run, it’s just that the second fails the authentication process (on the API server side) and returns an error code (properly) because it can’t verify the token sent back with the (missing) token saved in the session (because the session ID is not returned with the second request):
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import internal.GlobalVariable as GlobalVariable
loginResponse = WS.sendRequest(findTestObject('SOAP/login'))
def headerFields = loginResponse.getHeaderFields()
String responseXml = loginResponse.getResponseBodyContent()
def loginValues = new XmlSlurper().parseText(responseXml)
def authToken = loginValues.return.client.authToken.text()
GlobalVariable.G_authToken = authToken
Note that loginResponse.getHeaderFields() always returns null, even if I add [‘Set-Cookie’] or the name of any other header field. In the debugger, when I look at the ResponseObject, I see the header Map is empty (null).
What am I doing wrong here?
GlobalVariable.G_authToken = authToken
note sure how you use that in the second request
Possible solution, parametrize the second request and pass the authToken as n object ll parameter straight in your script to avoid headaches with different instance of GlobalVariable class created during run-time, e.g:
WS.sendRequest(findTestObject('SOAP/manage', [('authToken') : authToken])))
As for the session ID of the 1st request… where/how is that used in the 2nd request?
The authToken, UID, and device ID (three variables required for authentication) are stored on the server as part of the session. They are compared with parameters sent to the server as part of the request. Without the session ID, the server can’t reference the stored variables to compare with those sent with the request. (NOTE: Unlike languages like PHP, J2EE stores session variables on the server side, not in a cookie on the client side.)
The authToken, UID, and device ID (three variables required for authentication) are stored on the server as part of the session.
well … i understand this. but what i have asked is … where did you attempt to pass the session ID in the second request? I see no code refering to it
For my eyes, the authentication sequence (from the code you wrote) is:
- send the login request with UID, ID, pass > retrieve token
- send manage request using the retrieved token.
we don’t care what/how actually the server do with it, we only care what we have to put in the requests
Is that the right workflow or I am missing something?
Can you reproduce such sequence using another tool, e.g. Postman … or SoapUI (I think the 2nd is more suitable for SOAP requests)?
- The client makes a request to the authorization server sending the
client ID , the
client secret , along with the
audience and other claims claims.
- The authorization server validates the request, and, if successful, sends a response with an access token.
- The client can now use the access token to request the protected resource from the resource server.
Am I reading wrong that spec?
Usually when i saw such auth sequence’s, the needed data for 2nd call is received in the body response of the 1st call, not in header … or it is a combination of the data received from the 1st request and parameters sent with the 1st request.
So you don’t have to retrieve the clientId from the 1st request, but just reuse-it since you have it on your machine.
There is no code referring to the session ID in the second request because I could not figure out how to retrieve it from the response of the first request. In fact, I can’t figure out how to retrieve ANY header information from the first request because the method mentioned in all the documentation I have found def headerFields = loginResponse.getHeaderFields() returns null no mater how I try it (e.g. - If I request a specific header field, such as [‘Set-Cookie’], which is present according to the HAR log file, a null is returned.) In fact, when single stepping through the code in debug mode, drilling down in loginResponse shows that the header fields contain no data at all - even though according to the Katalon documentation (unless I’m missing something), the complete HTTP header should be present.
The link you have is for OAuth 2.0, which is not the protocol I am using (and is inherently insecure). The session ID is required in order to retrieve validate the client sending the token with the data stored on the server.
It seems as though I will not be able to use Katalon for our testing since I can’t seem to be able to retrieve the session ID from the HTTP header and nobody seems to be able to give me an answer as to why I can’t, if it’s possible, or how if it is.
With SoapUI (ReadyAPI Pro) it works easily. There is a simple setting called “Maintain HTTP Session” that when enabled maintains the session cookie between requests.