jmeter dynamically sign / hash a url - jmeter

I'd like to test a restful web service which requires a custom authentication scheme (MD5 of the URL with a recent timestamp).
e.g. URL http://test.com/secret/stuff/csv_val?uid=123&ts=1388695589&sig=e8dcf859a079e8670a5765e3eb0413e4
Where csv_val is a dynamic value coming from a CSV file, uid is my user ID, ts is the current timestamp and sig is the MD5 of MY_SECRET_KEYhttp://test.com/secret/stuff/csv_val?uid=123&ts=1388695589
From my research I think I should be using a JSR223 pre-processor to generate the timestamp and MD5 but it is not clear how I can get access to the full URL inside the script. I found an SO post (How to connect Jmeter to Java class?) which looked very promising but doesn't seem to work for me.
So my question is: how can I get access to the HTTP request parameters (host, port, path, protocol, etc...) inside a pre-processor?

You can use user defined variables to store needed values. After that you construct your request the next way:
where values in ${...} are user defined variables. Values for them can be created in BeanShell, BSF or RS2323 preprocessor. Here is some API to work with UDV. Here is pretty similar question jmeter var.putobject variable use in other jdbc request, but it is ignored. And here is a link so that you can read csv_val from CSV file.

Related

Jmeter 5.3: Extract run time 'code_challenge' URL parameter value from request URL which is not shown in any response

We have one URL parameter as "code_challenge" which gets generated at run time, this value we need to extract so that from next runs it can be handled. However since this code value is not captured in any previous requests/responses and need to extract at run time, unable to understand how to achieve.
Tried Regular Extractor choosing URL radio button, but it captures the value from recorded script.
Steps followed:
Record script using Blazmeter (Browse URL xx.com>Click Login)
Redirected to URL(s) in which one of the url has "code_Challenge" parameter with run time value)
First URL is: accounts-xx.com/oauth2/oidcdiscovery/.well-known/openid-configuration> The response doesn't have any parameter values
Second URL is:
https://accounts-xx.com/oauth2/authorize?response_type=code&client_id=zzzz&scope=ituytutut&redirect_uri=xx.com/callBack&code_challenge_method=ooo&**code_challenge=dsfsdlfhl**
In above 3rd point url, Code_challenge value is generated at run time when executed steps from browser.
However If replayed the recorded script which would have already generated code value hence other requests would fail. Due to this, need to get the code value fetched.
The code_challenge is generated from WS02 service.
Jmeter version: 5.3
Please suggest, or should we need to use Selenium webdriver integration.
Regular expression which would extract the value from recorded script:
As per Mitigating Authorization Code Interception Attacks article:
code_challenge The client creates and records a secret cryptographically random string (the code_verifier), which is then encoded using URL safe base64 encoding to transform it into the code_challenge.
As per PKCE in WSO2 IS server article:
1.Plain:
If a code_challenge method is mention as plain or not mention at all it will take this plain value. Then code_challenge will like:
code_challenge = code_verifier
2. SHA256:
To have the code_challenge as SHA256, we should mention this in request otherwise plain value will be assumed.For SHA256 code challenge will be like
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
Here base64url is same as base64encoding(used so that all machine can identify as same value) but trailing “=” will be removed and “+” & “/” are placed by “-” & “_” to avoid unnecessary length in URL.(otherwise ‘+’ becomes ‘%2B’, ‘/’ becomes ‘%2F’ and ‘=’ becomes ‘%3D in URL)
As much as possible, it is better to select the code challenge method as SHA256 then the flow will become more secure and hard to guess(if someone try to brute force it)
So I think you need to add JSR223 PreProcessor and calculate/generate the code_challenge using the algorithm used by your server in Groovy language, store the value into a JMeter Variable and use it in the request.
You can leave the field value empty and then its value gets updated once the request is sent. But you won't see the value in the request.
I had a similar issue, it worked in my case.

In JMeter how do I set multiple dynamic variables in User Parameters or CSV Data Set Config

Very new to JMeter (and a long time Stack Overflow listener but first time caller so take it easy on me) so any help would be appreciated.
I am trying to set up a JMeter test that uses multiple dynamically generated access tokens to run across scenarios. I currently have a set of data using the CSV Data Set Config containing login credentials of a user's email and password for example:
email1#email.com,password1
email2#email.com,password2
Next I send a HTTP POST request to the Login service which generates an accessToken. Then, I am using the JSON Extractor to grab the generated accessToken. After that I am using the BeanShell Assertion to store the accessToken property/variable.
My issue seems to lie here in this last step since it will only store the last generated variable instead of each of the generated accessTokens. I want to be able to store/overwrite the grabbed accessToken for each email password combination. I would like it to modify/populate the CSV file like this:
email1#email.com,password1,accessToken1
email2#email.com,password2,accessToken2
I have also tried using the Pre Processor > User Parameters
Screen shot of User Parameters
I would like to have the "userBearerToken" variable update/overwrite along with the tests, but I cannot find a way to do so or if this can even currently be done.
I'm finding it difficult to word what I am trying to ask, but basically I want to store multiple dynamically generated variables (accessTokens that change and time out) and use them in other tests. I don't care which component can handle this (either the CSV or User Parameter), but I need to be able to store these variables with their corresponding email password credentials.
If you want to store the accessToken value into a JMeter property for using in other Thread Group(s) be aware that properties are global for the whole JVM and remain until JMeter is restarted so if you define a single accessToken property - each JMeter Thread (or iteration) will overwrite the value.
The solution is to use current thread (or iteration) number as prefix or postfix, this can be done using either __${__threadNum} function or relevant JMeter Variable depending on how iteration is defined or both.
Example setup:
In first thread group: ${__setProperty(access_token_${__threadNum},bar,)}
In second thread group: ${__P(access_token_${__threadNum},)}
Demo:
If you want to save the values into a file writing into the current one is not the best idea as you can (and most probably will) get malformed file due to a form of a race condition. So I would recommend using Sample Variables property instead.
If you add the next line to user.properties file:
sample_variables=email,password,accessToken
JMeter will store the variables named ${email}, ${password}, and ${accessToken} along with their values in the .jtl results file which is basically CSV file which can be re-used anywhere else.
However if you have a requirement to store only the credentials and the token you can go for the Flexible File Writer plugin and configure it to save the aforementioned variables values into a separate file, the relevant configuration would be as simple as:
variable#0,variable#1,variable#2
You can install Flexible File Writer plugin using JMeter Plugins Manager

HTTP Request path needs to be parameterized with UUID and a random URL

URL format is
www.something.com/something/api/{uuid}?code=gomundw0gjq2kbvc3g63whfr9usap5rurjaq5vui5vm6xbt9hhqa8hbcpto4yatwpn26v42t9
I need to make several calls to this GET Url and check performance of the feature.
uuid here is not just the UUID , but is specific to my application
UUID= accountid+identifierid+uuid, which will look like 1234+1234+123e4567e89b12d3a456426655440000
How should I arrange my Jmeter Test Plan.
My Plan would be:
write UUID generated to a file
Using any preprocessor call the file from file and write program to append to a different value in the csv which is account/identifierid.
Please help on this, can some one explain how I should logically arrange my test plan and code to get data to parameterize my path in HTTP Request sampler.
Thanks in Advance
You need to get accountid+identifierid information stored into CSV file. This is something you need to do on your own.
You can use CSV Data Set Config in order to get the information from that file while your test is running, example configuration would be:
UUID can be generated using __UUID() function
So your HTTP Request sampler configuration would be something like:

Automatically generate HTTP request URLs in JMeter

I have an API call URL similar to this:
http://domain.com/rest/getValues?apiKey=sdfsdf&customerId=2200&timestampBegin=2013-08-15%2018:00:00%20CEST&timestampEnd=2013-08-19%2018:00:00%20CEST
I would like to dynamically change the time stamps, as well as the customerId, picked from a given set of timestamps and customerIds. Is this possible to do in Jmeter (preferably through GUI)?
Assuming that you are have inputs coming from external CSV file, you can use CSV data set config as explained here.
Your test plan will look something like
Thread groups
CSV Data Set config (define the file path and the variable names. You will be able to read these variables in request.
HTTP Sampler
http://domain.com/rest/getValues?apiKey=sdfsdf&customerId=${custid}&timestampBegin=${begin}&timestampEnd=${end}

How to pass a random User/Pass (for Basic Authentication) with JMeter?

I'm using JMeter to stress test an API. I've got Basic Authentication set up - seems to be working great.
Now, i'm trying to randomize the credentials that JMeter passes across the wire. So, there's two ways I know I can do this.
Add a custom HTTP Header (via an HTTP Header Manager Element) and set then value to the random fields (ie. something I've read in from a csv file)
Use the HTTP Authorization Manager Element and pass in the username and password there.
Now, if I try and use method (1) above, I need to create the following header/data :-
Authorization: Basic <some Base64 encoded string in the format username:password>
eg.
Authorization: Basic OnVzZXIxOnBhc3Mx
Kewl. simple. BUT that header value is not getting passed across the wire :( I can add any other header type and it's passed across the wire..
hmm .. ok then .. lets try method (2).
Now that works .. but I can only hardcode in the username & password. I can't see how I can pass in a username VARIABLE (ie. ${usernmae} ) or a password VARIABLE (ie. ${password} ).... If it's hardcoded, then the server correctly replies with the correct page/data.
so .. can someone please help?
I would recommend trying the following:
Create a HTTP Authorization Manager Element
Setup the username and password to be variables, ${username} , ${password}
Create a CSV file with your usernames and passwords (do not use a header row)
create a CSV Data Set Config Element, with the variable names set to "username,password" (no quotes, and no space after the comma)
Each thread/loop will read a different value from the CSV file.
Alternately, if you want the value to be truely random for the login, there are some functions you can use to generate random numbers or send in the time of execution.

Resources