Pure Java REST API POST calls to Jenkins /reload or /restart always return status 403 forbidden, but work - rest

I'm getting an Exception when running this, but Jenkins actually executes the requested action:
URL url = new URL("https://somehost.com/jenkins/quietDown");
HttpURLConnection c= (HttpURLConnection) url.openConnection();
c.setRequestMethod("POST");
c.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString(("user:apiToken").getBytes()));
c.getInputStream().close();
Exception:
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 403 for URL: https://somehost.com/jenkins/
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at build.JenkinsClient.main(JenkinsClient.java:102)
Testing with Jenkins 2.164.3 and Java 8.

Setting this gets rid of the Exception:
connection.setInstanceFollowRedirects(false);
After hours I noticed how the stack trace contained a slightly different URL than the one I was posting to:
https://somehost.com/jenkins/
vs
https://somehost.com/jenkins/quietDown
It seems like Jenkins answers with a redirect (302 Found), which the HttUrlConnections follows by default to read from, which then for some reason caused that exception.
For the longest time, I tried to figure out a way to issue the POST request without calling connection.getInputStream(), but that seems to be the only call which actually triggers the request. If anyone knows a different way to issue a POST request with pure Java, please let me know.
I knew my URL and username:token stuff was correct because I tested with curl (which doesn't complain, even with the follow redirect option turned on):
curl -X POST https://somehost.com/jenkins/quietDown -u admin:token
curl -L -X POST https://somehost.com/jenkins/quietDown -u admin:token

Related

Getting connection timeout error while calling get access token Microsoft Graph API through REST POST call

I am trying to get access token from https://login.microsoftonline.com/{tenentname}/oauth2/v2.0/token endpoints though HttpClient post request. Applied required 4 parameters/headers with the same.
But I am getting connection timed out. Connection will be retried using another IP address (after trying with 7 different IP address) getting Shutdown connection error. Connection discarded.
Please find below code snippet.
HttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
HttpPost post = new HttpPost("https://login.microsoftonline.com/{tenentname}/oauth2/v2.0/token");
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("grant_type", "client_credentials"));
urlParameters.add(new BasicNameValuePair("client_id", {id_value}));
urlParameters.add(new BasicNameValuePair("client_secret", {secret_value}));
urlParameters.add(new BasicNameValuePair("scope", "https://graph.microsoft.com/.default"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
post.setHeader("Content-type", "application/x-www-form-urlencoded");
ClosableHttpClinet httpClient = HttpClients.custom().setConnectionManager(poolingConnManager).build();
ClosableHttpResponse response = httpClinet.execute(post);
System.out.println(EntityUtils.toString(response.getEntity()));
Same its worked with Postman without any proxy setting, I am getting proper response in Postman.
Please assist on the same.
Instead of using HTTPClient, i tried with Microsoft Graph Client (you can download from NuGet) and it worked for me. So i would suggest you to follow the steps.
Install the SDK
Configure the GraphClient
Make the call.
Also with specific to ivy dependency, here's the related thread.

Jersey REST GET is working but PUT not. The specified HTTP method is not allowed for the requested resource

I've been breaking my head over this for a few days now. This little sniplet is working fine (using Jersey 2.26-b03 on Tomcat).
#GET
#Path("/{code}")
public Response update(#PathParam("code") String code) {
System.out.println("!!!!!!!");
return Response.status(Response.Status.OK).build();
}
curl -i -X GET http://localhost:18270/nyx/rest/servervirtueel/SVM0000
HTTP/1.1 200 OK
Followed by a bunch of Jersey tracing I enabled. But if I only change the GET to a PUT (exactly the same method, just change the annotation):
#PUT
#Path("/{code}")
public Response update(#PathParam("code") String code) {
System.out.println("!!!!!!!");
return Response.status(Response.Status.OK).build();
}
curl -i -X PUT http://localhost:18270/nyx/rest/servervirtueel/SVM0000
HTTP/1.1 405 Method Not Allowed
Followed by HTML telling me that the "The specified HTTP method is not allowed for the requested resource". However, POST does work (changing the annotation again).
It turned out that the OWASP method whitelist valve was configured on Tomcat (Catalina) level to only allow GET and POST; this is a webapp that held only SOAP services until now. You do not see this in either web.xml's or server.xml, but it's in Catalina/localhost/webappname.xml.

JENKINS Authentication Fails

I am getting the following error while trying to trigger Jenkins job from any REST Client
Authentication required
<!-- You are authenticated as: anonymous
Groups that you are in:
Permission you need to have (but didn't):
hudson.model.Hudson.Read
... which is implied by: hudson.security.Permission.GenericRead
... which is implied by: hudson.model.Hudson.Administer
-->
</body> </html>
The request is getting triggered while using curl from terminal
I am using the following syntax
http://user:apiToken#jenkins.yourcompany.com/job/your_job/build?token=TOKEN
[ref :https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients]
ie. curl -X POST http://user:apiToken#jenkins.yourcompany.com/job/your_job/build?token=TOKEN
Check this "This build is parameterized " , select the credentials parameter from drop down.
Use this
curl -X POST http://jenkins.rtcamp.com/job/Snapbox/buildWithParameters --user "username:password"
It solved my authentication problem.
I hope it will help others too.
My development team's configuration settings were matrix-based security so I had to find my group and give my group workspace access.
1.Click on Manage Jenkins .
2.Click on Configure Global Security .
3.in matrix-based security change:
Overall - Read
Job - Build
Job - Read
Job - Workspace
Then
POST jobUrl/buildWithParameters HTTP/1.1
Host: user:token
Authorization: Basic dWdlbmxpazo4elhjdmJuTQ==
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Branch=develop
For me
https://user:password#jenkins.mycompany.org/job/job_name/build?token=my_token
in https://jenkins.mycompany.org/configureSecurity
disable CORS
hope this help
Try using the -u parameter to specify the credentials:
curl -u user:apiToken -X POST http://jenkins.yourcompany.com/job/your_job/build?token=TOKEN
I provided header Authorization parameter with value :
BASIC base_64encoded(username:password) and it worked fine.
Authorization Basic bmltbWljdjpqZX*********
Simply disable "CSRF Protection" in the global Security Options, because those URLs don't send post data identification.
focal point :
username:password#
curl -u user:apiToken -X POST http://username:password#jenkins.yourcompany.com/job/your_job/build?key1=value1&key2=value2 ...
If you are encountering this problem with jenkins api client in ruby.
I figured Jenkins is blocking all the get request, instead use api_post_request.
Also, you have to generate api token because normal password is not working anymore.
#client = JenkinsApi::Client.new(
server_url: "",
username: '',
password: ""
)
SITE_FILE_PATH = 'artifact/target/site'.freeze
#jenkins_uri=''
#jenkins_job_name=''
def latest_test_file_path
"/job/#{#jenkins_job_name}/job/master/lastSuccessfulBuild/#{SITE_FILE_PATH}/Test-Results/test-results.html"
end
puts #client.api_post_request(latest_test_file_path,{},true).body
you can set the parameter true if you want the raw response.
default parameter or passing false will just return response code.
Also make sure to construct the right prefix.
You can refer to the above snipped.

Getting an error while invoking a REST service using Javascript

I have developed a REST Web service to get resources, I am able to access it through Java/Spring Template and even the xml response is coming if I type the URI on browser.
But when I invoke the same URI using XMLHttpRequest in Java script I am getting the below error.
"XMLHttpRequest cannot load URI(actual uri with server name ..etc) . Origin file:// is not allowed by Access-Control-Allow-Origin."
Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101.
My JS code is as below.
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://localhost:8080/rest/apps", false );
xmlHttp.send( null );
Please let me know what would be the problem and help me to resolve this.
Regards,
Sreedhar
here Origin is the local file system, that you're loading the HTML page, that load call via a file:/// . the request is from the same origin. If you're trying to load from somewhere else then you will not get the Error.
Check For this answer

javax.xml.ws.soap.SOAPFaultException: Could not send Message - at JaxWsClientProxy.invoke - caused by HTTP response code: 401 for URL

I moved a working code from dev to test and encountered the following error(s) in test:
javax.xml.ws.soap.SOAPFaultException: Could not send Message.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:143)
......
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:472)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:302)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:254)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:123)
at $Proxy739.copyIntoItems(Unknown Source)
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: http://<sharepointportal>/_vti_bin/Copy.asmx
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:2046)
Environment specs:
Java 1.6
Tomcat 6
Eclipse Helios
Maven2
CXF 2.2.3
As a background work, tried to explore about the error in similar category
bad URL (ruled out as i am using same URL in dev and test. and the url, userid, password are all accessible from both the machines),
connection timeout( error is not 404 or it doesnt specify connection timed out... it says 401 response code for url)
Checked if all the jars and same versions are included in the test environment.
Can someone shed some light to understand and resolve the error?
please let me know if any more details are to be included.
401 is an authentication error.
Authentication fails either at the destination URL http:///_vti_bin/Copy.asmx (3 slashes ?) or on a forward proxy on the way.
Are you connecting to _vti_bin via a proxy in test ?