Generate authentication token and use it throughout the session in Gatling - scala

I have a scenario where I am hitting the keyCloak requests and using the token as a header in the other HTTP requests.
My problem is for 100 users it is generating 100 tokens so I am looking for the solution in which keyCloak request is hit only once and the token is used throughout the performance run.
Sample code snippet for the reference:
scenario("CMS service")
.exec(KeycloakToken.request(conf))
.exec(getOffers.request(conf))
.exec(offerById.request(conf))

Use feeder https://gatling.io/docs/current/session/feeder/ .
1) Create feeder
val feeder = Iterator.continually(Map("token" -> "dG9rZW4="))
2) Add feeder to scenario
scenario("CMS service")
.feed(feeder)
.exec(...)
3) Pass value via Gatling EL https://gatling.io/docs/current/session/expression_el
In your http request add token
http(...)
.post(...)
.header("your token header", "${token}")

Related

connect to REST endpoint using OAuth2

I am trying to explore different options to connect to a REST endpoint using Azure Data Factory. I have the below python code which does what I am looking for but not sure if Azure Data Factory offers something out of the box to connect to the api or a way to call a custom code.
Code:
import sys
import requests
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
import json
import logging
import time
logging.captureWarnings(True)
api_url = "https://webapi.com/api/v1/data"
client_id = 'client'
client_secret = 'secret'
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url='https://webapi.com/connect/accesstoken', client_id=client_id, client_secret=client_secret)
client = OAuth2Session(client_id, token=token)
response = client.get(api_url)
data = response.json()
When I look at the REST linked service I don't see many authentication options
Could you please point to me on what activities to use to make OAuth2 working in Azure Data Factory
You would have to use a WebActivity to call using POST method and get the authentication token before getting data from API.
Here is an example.
First create an Web Activity.
Select your URL that would do the authentication and get the token.
Set Method to POST.
Create header > Name: Content-Type Value: application/x-www-form-urlencoded
Configure request body for HTTP request.
..
Format: grant_type=refresh_token&client_id={client_id}&client_secret=t0_0CxxxxxxxxOKyT8gWva3GPU0JxYhsQ-S1XfAIYaEYrpB&refresh_token={refresh_token}
Example: grant_type=refresh_token&client_id=HsdO3t5xxxxxxxxx0VBsbGYb&client_secret=t0_0CqU8oA5snIOKyT8gWxxxxxxxxxYhsQ-S1XfAIYaEYrpB&refresh_token={refresh_token
I have shown above for example, please replace with respective id and secret when you try.
As an output from this WebActivity, you would receive a JSON string. From which you can extract the access_token to further use in any request header from further activities (REST linked service) in the pipeline depending on your need.
You can get the access_token like below. I have assigned it to a variable for simplicity.
#activity('GetOauth2 token').output.access_token
Here is an example from official MS doc for Oauth authentication implementation for copying data.

How can I a Google Api restful endpoint using service key?

I'm using postman to memic a restful api call and trying to access google sheets API end point. When I try to access my endpoint it returns:
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"status": "PERMISSION_DENIED"
}
}
which is fair enough as I did not use my API key. I created a service account and got a json file, but I plan to access using a rest endpoint so need to pass token in header but I'm not sure how.
I looked at the json file and wasn't sure what to extract in order to pass it for my rest call.
Has anyone been able to do this successfully?
Before calling Google Services from Postman, you would need to re-create the flow for getting an access token form service account credentials :
build and encode the JWT payload from the data from credentials files (to populate aud, iss, sub, iat and exp)
request an access token using that JWT
make the request to the API using this access token
You can find a complete guide for this flow is located here: https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests
Here is an example in python. You will need to install pycrypto and pyjwt to run this script :
import requests
import json
import jwt
import time
#for RS256 you may need this
#from jwt.contrib.algorithms.pycrypto import RSAAlgorithm
#jwt.register_algorithm('RS256', RSAAlgorithm(RSAAlgorithm.SHA256))
token_url = "https://oauth2.googleapis.com/token"
credentials_file_path = "./google.json"
#build and sign JWT
def build_jwt(config):
iat = int(time.time())
exp = iat + 3600
payload = {
'iss': config["client_email"],
'sub': config["client_email"],
'aud': token_url,
'iat': iat,
'exp': exp,
'scope': 'https://www.googleapis.com/auth/spreadsheets'
}
jwt_headers = {
'kid': config["private_key_id"],
"alg": 'RS256',
"typ": 'JWT'
}
signed_jwt = jwt.encode(
payload,
config["private_key"],
headers = jwt_headers,
algorithm = 'RS256'
)
return signed_jwt
with open(credentials_file_path) as conf_file:
config = json.load(conf_file)
# 1) build and sign JWT
signed_jwt = build_jwt(config)
# 2) get access token
r = requests.post(token_url, data= {
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": signed_jwt.decode("utf-8")
})
token = r.json()
print(f'token will expire in {token["expires_in"]} seconds')
at = token["access_token"]
print(at)
Note the value of the scope: https://www.googleapis.com/auth/spreadsheets
Probably, you can do all the above flow using Google API library depending on what
programming language you prefer
The script above will print the access token :
ya29.AHES67zeEn-RDg9CA5gGKMLKuG4uVB7W4O4WjNr-NBfY6Dtad4vbIZ
Then you can use it in Postman in Authorization header as Bearer {TOKEN}.
Or using curl :
curl "https://sheets.googleapis.com/v4/spreadsheets/$SPREADSHEET_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Note: you can find an example of using service account keys to call Google translate API here

How to maintain same session across multiple requests in rest-assured?

Pre-req:Rest-assured api tests with Java
Step
1. Launch URL and get login ticket - code snippet below to get login ticket
RestAssured.baseURI = "https://ve4al10p:453";
RestAssured.useRelaxedHTTPSValidation();
Response res =
given().
header("Content-Type","application/json").
when().
post("/i/login?action=lt").
then().
assertThat().statusCode(200).
extract().response();
res.prettyPrint();
Output: Notice login ticket
lt":"LT-12370-j4znjFQkGMXMjlT3uKJ"
Step 2. Use login ticket and perform login with username and password.
I extracted login ticket and passed to next request (continued snippet).
CookieFilter cookieFilter = new CookieFilter();
Response res1 = given().
filter(cookieFilter).
header("Content-Type","application/json").
queryParam("lt",loginticket).
queryParam("username","user1").
queryParam("password","pass1").
when().
post("/i/login?service=https://ve4al10p:443/spa").
then().
assertThat().statusCode(200).
extract().response();
res1.prettyPrint();
Output: Notice it again creates a new login ticket, that means a new session and fails give expected output.
**"lt":"LT-12369-u6osMkesdg6RQu9JPoDARL4D"**
Note: I also noticed the sessions for above requests and both are different.
Expected Output: I want to use same login ticket and maintain same sessions.
you can get the SessionID/cookie from login and pass this as SessionID to next request as header to maintain single session.
for eg :
String JsessionID = given().header(h1).body(payload).when().post(basepath).thenReturn().cookie("JSESSIONID");
given().headers(JsessionID).body(body).when().post();
How about send request with cookie?
Let's say you got access_token in cookie after login success, you can send request within the access_token in cookie:
String token = given()
.contentType(ContentType.JSON)
.body(payload)
.log()
.all()
.when()
.post(loginUrl)
.thenReturn()
.cookie("access_token");
Cookie tokenCookie = new Cookie.Builder("access_token", token)
.setSecured(true)
.setComment("some comment")
.build();
assertEquals(given()
.cookie(tokenCookie)
.when()
.get(nextRequest)
.statusCode(), 200);

How to automate dynamic token generated by a URL for Rest API in SOAPUI?

For my project
I have created test cases in SOAPUI for Rest project.
I have to pass token in header for each test steps that I have added in the test cases.
Also the token validity only for 1 hour. So every hour I have to enter the token in the headers.
I want to know is there any way automate this token entry and generation dynamically ?
For now what I am doing is getting token every time by refreshing the URL in every 1 hour and putting it manually in header of every test case and test steps.
You could use something like the following Groovy script as the first test step of your test case. This gets your authorisation token from whatever service you use and sets it in your request header:
def authorisationToken = // Retrieve a new token from your authorisation service
// Get the headers for the request
def restRequest = testRunner.testCase.getTestStepByName('REST request')
def headers = restRequest.httpRequest.requestHeaders
// Set the token as a header. Remove it first in case it already exists
headers.remove("Authorisation") // Or whatever your header is called
headers.put("Authorisation", authorisationToken)
restRequest.httpRequest.requestHeaders = headers
If you need to, you could also create a custom property at, say, the test suite level, then set this property after you retrieve it:
testRunner.testCase.testSuite.project.setPropertyValue("Authorization", authorisationToken)
Then, you could use it anywhere you need with ${#TestSuite#authorisationToken}

Gatling-tool Extracting cookie data

I'm currently writing a test simulation with gatling and I've hit a brick wall. One of my post requests has an odd requirement. the request is:
.post("/checkout/cart/add/product/form_key/")
This post request wont complete with appending the form key on the end of the URL, the form key is stored in a cookie called: CACHED_FRONT_FORM_KEY
I need a way to grab the value in that cookie from the gatling cookiejar and to be used in the post request as follows:
.post("/checkout/cart/add/product/form_key/${FORM_KEY}")
I have done some googling and found a similar request:
https://groups.google.com/forum/#!topic/gatling/gXosGVnUuZA
But I'm unsure of how to implement this into a simulation file, I'm currently using gatling 1.4.3. Any assistance would be most appreciated.
Using the Gatling 2 API, you can access cookies as follows:
.exec( session => {
import io.gatling.http.cookie._
import org.asynchttpclient.uri._
import io.netty.handler.codec.http.cookie.ClientCookieDecoder.LAX.decode
val cookies = session("gatling.http.cookies").as[CookieJar].get(Uri.create("https://www.someSite.com"))
// for (ck <- cookies ) {
// val cc = decode(ck.toString())
// println(s"${cc.name} === ${cc.value}");
// }
val ck = cookies.filter( cookie => decode(cookie.toString()).name == "CookieName")
println(decode(ck.toString()).value)
session
})
Uncomment the iterator to view all the cookies in the current session
You can use a regexHeader check on the Set-Cookie reponse header in order to capture the cookie value.
Don't have enough rep to comment, so I'll add another answer.
For this Magento scenario I needed the form key, but using headerRegex("Set-Cookie","CACHED_FRONT_FORM_KEY=(.*)").saveAs("formkey") would return a value like
1Nt86VNYoPP5WUtt; path=/; domain=example.com
By using the following regex, I was able to extract just the 1Nt86VNYoPP5WUtt value
headerRegex("Set-Cookie","CACHED_FRONT_FORM_KEY=([^;]+)").saveAs("formkey")
I then used it in my HTTP Post like
http("add_to_cart")
.post("/checkout/cart/add/product/12345")
.formParam("form_key", "${formkey}")
Using the HTTP Helper getCookieValue is another way to grab cookie data:
// add cookie to the session as CACHED_FRONT_FORM_KEY
.exec(getCookieValue(CookieKey("CACHED_FRONT_FORM_KEY")))
.exec { session =>
println(session("CACHED_FRONT_FORM_KEY").as[String]) // `.as[]` unwraps the value from the session object
session
}
.post("/checkout/cart/add/product/form_key/${CACHED_FRONT_FORM_KEY}")
Sources
Gatling HTTP Helpers
Gatling Debugging