I am using the Http Request plugin in Jenkins to run HTTP Request towards an API.
I need to use a token for the authorization. So I configured on Jenkins global configuration a secret text credential with the token and gave it the id segron.
Then I run the API Call in Jenkins like this
httpRequest url: "http://10.10.10.10:8080/api/run/", httpMode: 'POST', contentType:'APPLICATION_JSON',authentication: 'segron'.
But when I run the pipeline I got this error.
java.lang.IllegalStateException: Authentication 'segron' doesn't exist anymore
I use the same plugin to run other API Call using username / password as credentials, and it works perfectly fine.
Any help/experience regarding this?
I had a similar issue. In my case the Http Request plugin did not like the API-token stored as "secret text" in Jenkins.
After changing it to a username/password credential type it worked for me.
username set to the user that owns the API-token
password field gets the API-token from Bitbucket
This is a bit unexpected as Bitbucket related APIs like notfiyBitbucket worked perfectly fine with API-token in secret text credentials, but Http Request plugin does not seem to support that.
It does work the other way around though, notifyBitbucket also works with username/password credential type, so no need to store the API token twice now.
I assume this is the place where the exception is thrown: https://github.com/jenkinsci/http-request-plugin/blob/master/src/main/java/jenkins/plugins/http_request/HttpRequestExecution.java#L239
Looking at the lines above that, only a limited set of credential types seem to be supported. The exception should probably at least emit a more descriptive error message to understand what is wrong.
Related
I am working on setting up a load test suite for a site which has an OAuth2 login mechanism on another server (PKCE I believe it is), so when I click login-button I am tranfered to another site to perform the actual login, which then transfers med back to the main site.
This login site takes my credentials and in return gives the browser a code_challenge and some .js-files, from which I believe the browser later on create a Bearer token and place it in the browsers Session Storage.
This, as I understand it, cannot be replicated in JMeter alone, but it can be done if using Webdriver. Therefore I've set up a webdriver testcase in JMeter which performs the login and saves the used state, code_challenge and Bearer token in JMeter User Variables to be used later on in the load test (this all works fine).
The issue here is when I try to use the bearer token in a JMeter HTTP(S) Request I get the following error in response header:
WWW-Authenticate: Bearer error="invalid_token", error_description="The audience '<censored>' is invalid"
These are the headers for one of the GET requests with bearer token (which is previously recorded)
The bearer is collected with this piece of code
It doesn't matter if I'm using Firefox or Chrome webdrivers, the issue is the same.
So either I am trying to do something which cannot be done (re-use generated Bearer from Webdriver in JMeter), or I am missing something I do not understand. Help please?
I think you need to add Bearer to the value of the Authorization header like:
Also I don't think you need to kick off the real browser, well-behaved JMeter script is supposed to act like a real user using a real browser so my expectation is that you should be able to extract the token using HTTP Request samplers and suitable Post-Processors
For a single thread (functional test) the browser is okayish, but modern browsers are very resource intensive (one instances takes a CPU core and a couple of gigabytes of RAM) so when it comes to real load test execution you will need really powerful hardware in order to handle this authentication mechanism so it's better to stick to JMeter's HTTP Request samplers
I found the issue!
I had extracted the id_token and not access_token from the Session storage which of course was not valid as a Bearer token. They looked very much alike but was not the same, and I missed that.
On Postman, I can get new access token for OAuth2.0 by providing callback URL, auth URL and client ID.
I want to break this task down on JMeter because I cannot find this function there. From my understanding, it is divided into authenticate -> authorise -> call back.
Authenticate
URL = https://xxxxx/login
Result = Authorising URL
Authorise
URL = https://xxxxx/oauth/authorize?client_id=mmm&redirect_uri=https://yyyyy/auth/callback&response_type=code
Result = code (e.g. zzz)
Call back
URL = https://yyyyy/auth/callback?code=zzz
Result = token
As I used HTTP(S) Test Script Recorder on JMeter, I got the three actions mentioned above. When I reran them, it told me this error on Authenticate part: <oauth><error_description>Full authentication is required to access this resource</error_description><error>unauthorized</error></oauth>.
To make sure that it was not about the program I use, I did it on Postman and found this error as well.
I wonder how I can break OAuth2.0 Get New Access Token feature into basic API settings in order to get access token on Postman or JMeter.
Dont' compare these tools:
Postman is an Electron application, it's basically a heavily customised Chromium web browser + NodeJS
According to JMeter main page
JMeter is not a browser, it works at protocol level. As far as web-services and remote services are concerned, JMeter looks like a browser (or rather, multiple browsers); however JMeter does not perform all the actions supported by browsers. In particular, JMeter does not execute the Javascript found in HTML pages. Nor does it render the HTML pages as a browser does (it's possible to view the response as HTML etc., but the timings are not included in any samples, and only one sample in one thread is ever displayed at a time).
If you can obtain the token using Postman you can just add HTTP Header Manager to your JMeter Test plan and configure it to send Authorization header with the value of Bearer YOUR_TOKEN_FROM_POSTMAN and JMeter should let you in.
After testing, I found that Postman's OAuth 2.0 Get New Access Token popped up a login page of targeted URL where I needed to fill in the username and the password so that the token could be obtained.
As I tried breaking down APIs required for this login, it required GET of that https://yyyyy and POST of that https://xxxxx/login. Click Send for POST, with username and password contained in form-data, then click Send for GET. The GET response would contain such the token.
However, just putting the aforementioned GET and POST APIs into one thread group did not work on JMeter. As I used HTTP(S) Test Script Recorder to no avail, I went with BlazeMeter and realised that it was using Transaction Controller containing 1) GET of https://yyyyy 2) POST of https://xxxxx/login. With these two arranged top-down, the job would be successful. The token was contained in the response of 2).
For now, this has been my discovery which answers my question.
Try BlazeMeter.
I have sent a soap service for which I have to send basic auth (username and password) along with request and header values in qaf. I tried adding username and password in application.properties file but the service is throwing internal server error. Please guide me how can we do it.
If it is basic authentication you can try providing credential in url, For example: http://user:pwd#url.com. Other alternate is register client that takes care of authentication using property rest.client.impl. Few of ready to use implementations are available with qaf-support-ws library. You can try BasicAuthRestClient as below:
rest.client.impl=com.qmetry.qaf.automation.rest.client.BasicAuthRestClient
rest.client.basic.auth.username=username
rest.client.basic.auth.password=password
This should work for any webservice call regardless of type rest or soap. Keep in mind that in case of soap, method always be POST
I'm a newbie to this stuff so downloaded the samples which is all fine and I thought I could see what was going on and what I needed to do. However, got a bit stuck for no obvious reason so I wondered if anyone could maybe give me some hints.
I'm trying to engineer Cognito authentication and identity into an old Apache Struts 1 legacy web application written in Java, so all the activity needs to be server-side. Using the Cognito https://xxx.auth.xxx.amazoncognito.com/login? URL I can successfully authenticate and get an auth code back using this URL providing my client id, redirect URI and response_type=code so all good thus far.
If I then create an HttpClient (as per the sample code in Github) and call the token URL https://xxx.auth.xxx.amazoncognito.com/oauth2/token and write various parameters to the request body (grant_type=authorization_code, client_id=as previously, redirect_uri=my URI and code=auth code just returned), I get an "unauthorized_client" message returned. But the code is valid albeit for authorization, and the client_id is correct because I used it previously.
My log:
Cognito following successful signin, continuing to url http:[redacted]/passport/CognitoHandlerSignIn.do?code=62eeb0b1-a76b-489b-bd28-e42023a497bd
(this was the /login succeeding)
Callback from Cognito received
(following is the log dump of the /oauth2/token URI called to)
Cognito token signin URL is https:[redacted].amazoncognito.com/oauth2/token
HTTP request header, added Authorization=Basic M29wcGR0azdpYzF2YjloNGd0OTQzNXYxcmI6MW9mMmFsaWNzZGR2dHZ1NmFkOHRuc2s4cnJ0cXEyYm0yc3RqbG1mcmkyamhkdXBubG1wMw==
HTTP request header, added Content-Type=application/x-www-form-urlencoded
HTTP request body, added grant_type=authorization_code
HTTP request body, added
redirect_uri=https%3A%2F%2F<redacted>%2Fpassport%2FCognitoHandlerSignIn.do
HTTP request body, added code=62eeb0b1-a76b-489b-bd28-e42023a497bd
HTTP request body, added client_id=[redacted]
HTTP request is sun.net.www.protocol.https.DelegateHttpsURLConnection:https:
[redacted].auth.eu-west-1.amazoncognito.com/oauth2/token
HTTP Json result=<{"error":"unauthorized_client"}>
org.json.JSONException: JSONObject not found.
at org.json.JSONObject.get(JSONObject.java:454)
at
What's wrong with this picture? I tried also adding client_id, code as URL parameters but I just get an "invalid_client" message instead.
I also tried using the /oauth2/token URI directly from the Struts app to provide a token but it returns the id_token using # rather than ? in the parameter list so it is client-side only and hence can't be intercepted by the Struts app and so will be a pain to forward to the server, but I could write some Javascript to do it if I had to. It doesn't seem the path of least resistance, though, as it seems wrong that the pure Java server side call doesn't work so I must be doing something wrong which isn't obvious to me.
I am trying to build a service that authenticates users using an oauth 1 signed request. The request includes an oauth token, signature, nonce, and consumer key. The server has access to the corresponding secrets, but it is unclear how to use the oauth gem to validate the token and retrieve the corresponding user. The token was originally generated using the oauth-rails plugin, but the validation needs to take place on a different server from the original rails application (but has access to the same underlying database).
How can I use the oauth gem to accomplish this?
I have looked through the source for the oauth and oauth-plugin gems, but I can't tell where this validation actually happens. Almost all of the documentation I can find refers to using the oauth gem as a consumer, not a provider.
I finally figured out the answer to this, so I'll put it here in the hopes of helping someone in the future.
Once you've retrieved the AccessToken and ClientApplication objects from the underlying database and checked the nonce and timestamp, verifying the signature is as easy as:
signature = OAuth::Signature.verify(request, {}) do |sigblock|
[token.secret, ca.secret]
end
If the signature checks out, signature will be true. Beware - if you're behind an http proxy such as nginx, the SERVER_PORT environment variable may not be correctly set for https requests and you may have to set it manually. If this (or any other seemingly tiny part of the request) is off, it can cause the signature verification to fail even if the request is valid.