I'm trying to get an access token in Jmeter, and it works fine with postman, but I end up with an error in response in Jmeter saying
{
"error":"invalid_grant",
"error_description":"The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"status_code":400
}
Postman Body
Header in postman
I get access token as json response when i post this request
My setup in Jmeter looks as follows:
HTTP request
HTTP Header
I get following response when i run the test in jmeter
{
"error":"invalid_grant",
"error_description":"The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
"status_code":400
}
Given you send the same requests you should be getting the same responses so most probably the requests differ somewhere somehow.
You need to compare raw request body from Postman and the same from JMeter using View Results Tree listener
One obvious difference is missing Accept header in JMeter.
It might be the case that variables like ${_code} and ${base64HeaderValue} don't have their respective values, you might want to check them using Debug Sampler
And last but not the least, if your request works in Postman you can just record it using JMeter's HTTP(S) Test Script Recorder, just configure Postman to use JMeter as the proxy
And next time you run the request in Posman JMeter will capture it and store the relevant HTTP Request sampler (with the HTTP Header Manager) under the Recording Controller
Related
I've automated OAuth2.0 in Katalon to get the token code. The Access token code is replicated as expected in Response with 200 OK.
Now I want to use that Access Token Code and hit another POST API. Can we declare that response as global variable or in HTTP Headers?
I'm currently trying to retrieve a user token from the keycloak token endpoint using a POST request (instead of using one of the designated adapters). I have set up a keycloak realm and added my own machine as a client. In the documentation the Token Endpoint is described as:
/realms/{realm-name}/protocol/openid-connect/token
As far as I have read in the openid specification, I will need to set the body parameter grant_type=authorization_code as well as the parameters code and redirect_uri. I will also need to set the Authorization header, for which I will need a Basic Token.
So far I will get the response:
"error": "unauthorized_client", "error_description":
"INVALID_CREDENTIALS: Invalid client credentials"
Where do I get the Basic Authorization Token from? I expected that I need to provide a username and a password, since the JWT token is what I'm trying to recieve as response. Do I need to set the redirect_url if I just want to request a token?
Keycloak offers more than one way to retrieve a user access token, following the OpenId Connect spec. Here you have the steps to do it for Authorization code flow (the one recommended for web applications) according to the openid connect spec: https://rograce.github.io/openid-connect-documentation/explore_auth_code_flow
Basically, if you're not using any adapter, when detecting a request to some protected resource you should:
Perform a redirection to the keycloak login page (keep in mind keycloak uses the REALM entity, so you'll need to specify it too):
HTTP/1.1 302 Found
Location: https://mykeycloakinstance.org/auth/realms/demo/protocol/openid-connect/auth?
response_type=code
&scope=openid
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
You'll need to keep the state value in the client, as it needs to survive the redirection process:
It is recommended that client’s use this parameter to maintain state
between the request and the callback. Typically, Cross-Site Request
Forgery (CSRF, XSRF) mitigation is done by cryptographically binding
the value of this parameter with a browser cookie.
You don't interact with username/passwords. The keycloak authentication page does. Once the login is successful, it will redirect to your page with a valid code:
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
Here you'll need to either check that the state is the one you originally sent (you may need to track it through web session, using cookies) and also to obtain the token using that code. You do a POST to the authorization endpoint with this code:
POST /auth/realms/demo/protocol/openid-connect/auth HTTP/1.1
Host: https://mykeycloakinstance.org
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
This is the flow in summary, I haven't tested the code myself, so use it as an example and don't hesitate to fix it if you consider ;-)
See also:
What are Keycloak's OAuth2 / OpenID Connect endpoints?
I want to test an API which has the followoing instruction:
This API requires the caller to have an authenticated user web session.
When I login to the application and send a GET request in other tab it works. But I want to send a PUT request now so I cannot use browser. How can I have an authenticated user session while sending request through some other rest client. For eg: postman/ mozilla rest client.
I have tried logging into application through chrome and then using postman rest client. But it did not work. I have also tried Basic authentication providing application username and password.
So, given you mentioned you're using JWT, your API is most likely handing out this token upon logging in. At this moment your web client (javascript?) is probably storing it somewhere (cookie, local storage, session storage… – you can use your browser's dev tools to inspect). For all subsequent requests, this token is attached. If this token is getting persisted as a cookie, the browser itself takes care of attaching it to every request. If it is persisted somewhere else, your client has to "manually" attach this token to every request.
If you want to test your API call, first you need to login and get your hands on the token. Then, for all authenticated requests, you need to attach this token (probably as the Authorization HTTP header).
I maybe missing an important piece of jwt concept but I'm having a hard time finding info on where the server is supposed to include the generated json web token in the response and where the client is supposed to include it in the subsequent requests. Are there any rules/guidelines/best practices on that?
The JWT should be sent to the client in the response body. In the subsequent requests you've got to include an header field called Authorization with the token.
Check this link for more details.
I want to invoke a REST service that is hosted on WAS.
I would like to know how to set the ltpa token in the HTTP Request header while invoking the service using SOAPUI.
Can I set the token in the Cookie field of the header?
If so, what is the format ?
You must set this value in the cookie. My answer works on our WAS 8.5 servers. The cookie value must be:
LtpaToken2=<your token value goes here>
or
LtpaToken=<token here>
NOTE: you must have generated this token in the same realm as your server is running. If you have different realms, dev/test vs. production, your tokens don't work across these realms.
Be sure you have No Authentication selected in SOAPUI so you can validate that the token is working.