Question

I've seen similar posts to this on SO, but not quite exactly what I am trying to do (or at least no full examples of a command to run).

I am trying to remotely trigger a parameterized build on Jenkins using curl. I have 'Prevent Cross Site Request Forgery' enabled so I also need to pass a valid crumb.

The script I have is below:

#!/bin/bash

json="{\"parameter\": [{ \"P1\": \"param1\", \"P2\": \"param2\", \"P3\": \"param3\" }]}"
crumb=`curl "http://SERVER/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)"`

curl -v -H $crumb -X POST http://SERVER/job/JOB_NAME/buildWithParameters -d token=runme --data-urlencode json="$json"

I've also tried modifying the URL I'm passing to curl to either:

USERNAME:APITOKEN@SERVER

and

USERNAME:PASSWORD@SERVER

Output from curl is:

* About to connect() to SERVER port 8080 (#0)
*   Trying SERVER... connected
* Connected to SERVER (SERVER) port 8080 (#0)
* Server auth using Basic with user 'USERNAME'
> POST /job/JOB_NAME/buildWithParameters HTTP/1.1
> Authorization: Basic bjAwNjY5MjI6YWxLaW5kaTg=
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.1.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
> Host: SERVER:8080
> Accept: */*
> .crumb:776eb589e8b930d9f06cfc2df885314c
> Content-Length: 168
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 403 No valid crumb was included in the request
< Content-Type: text/html;charset=ISO-8859-1
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Length: 1469
< Server: Jetty(8.y.z-SNAPSHOT)
<

So it looks like I'm not passing the crumb properly, but I'm not sure what the correct format of the command should be.

Was it helpful?

Solution 2

The correct format is as follows:

curl -H ".crumb:xxxxxxxxxxxxxxxxxxxxxx"

OTHER TIPS

What worked for me:

SERVER=http://localhost:8080
CRUMB=$(curl --user $USER:$APITOKEN \
    $SERVER/crumbIssuer/api/xml?xpath=concat\(//crumbRequestField,%22:%22,//crumb\))

curl --user $USER:$APITOKEN -H "$CRUMB" -d "script=$GROOVYSCRIPT" $SERVER/script

This worked for me:

obtain crumb $ wget -q --auth-no-challenge --user yourUserName --password yourPassword--output-document - 'http://myJenkins:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

Now Run Jenkins Job $ curl -I -X POST http://yourUserName:yourPassword@myJenkins:8080/job/JOBName/build -H "Jenkins-Crumb:44e7038af70da95a47403c3bed5q10f8"

HTTP/1.1 201 Created Date: Fri, 28 July 2017 09:15:45 GMT X-Content-Type-Options: nosniff Location: http://myJenkins:8080/queue/item/17/ Content-Length: 0

This worked for me, I tried to used solutions already mentioned in this page but they had to be adapted a bit due to (a) referer and (b) cookie. Jenkins version 2.204

sh script:"""

COOKIE_PATH=/tmp/cookie_jenkins_crumb.txt

CRUMB=\$(curl -s -c \$COOKIE_PATH -H '${jenkins_referer}' 'https://useridhere:${jenkins_live_token}@jenkins.example.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)' )
# https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained
# https://wiki.jenkins.io/display/JENKINS/Remote+access+API#RemoteaccessAPI-CSRFProtection
# but a bit adjusted as it is not exactly usable as it is in the documentation page.
# We discovered that the CRUMB should be identical because it
# is paired with a cookie. Thus save the cookie, it is important.

sed -i 's/ORGANIZATION/${PROJECT_NAME}/g' ${jenkins_credentials_json_template_file_path} 
# a json file with labels for quick replacements.

# cat ${jenkins_credentials_json_template_file_path}

# https://support.cloudbees.com/hc/en-us/articles/360030526992-How-to-manage-Credentials-via-the-REST-API
curl -s -b \$COOKIE_PATH -u useridhere:${jenkins_live_token} -H '${jenkins_referer}' -H \"\${CRUMB}\" -X POST --data-urlencode json@${jenkins_credentials_json_template_file_path} 'https://jenkins.example.com/credentials/store/system/domain/_/createCredentials'
"""

This Worked

crumb=$(curl -u "user:pass" -s 'http://jenkins_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')

curl -u "user:pass" -H "$crumb" -X POST **http://jenkins_URL/job/ENV/build?delay=0sec**

Note: Get this POST URL by right click and copy the build now link.

This is emphasis on @seeker 's answer.

Pay extra attention to getting the crumb step

As the other answers mentioned, the crumb you get may differ depending on the browser you use to browse to Jenkins, be it Chrome, Curl or WGet.

But, and this is an important but, the crumb that I used for the CURL command is the one I got from the WGET command. It isn't the crumb I got from the CURL -X GET command.

I am not clear on why this is the case, but like in @Seeker 's answer, this worked for me.

I got different crumbs when

  1. Browsing to http://qajenkins:8080/crumbIssuer/api/xml

  2. Browsing to http://10.143.18.43:8080/crumbIssuer/api/xml (qajenkins = 10.143.18.43)

  3. Running

    curl -X WGET http://10.143.18.43:8080/crumbIssuer/api/xml

  4. Or running

    wget -q --auth-no-challenge --user raamee --password 12345678 --output-document - 'http://10.143.18.43:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)';echo

In order to get the curl command

curl -X POST -H "Jenkins-Crumb:2e03fc96f387abggga6581fe5883a14a" http://10.143.18.43:8080/view/Raamee_phase_2/job/test_remote_api_triggerring/buildWithParameters?token=MY_TOKEN --user "raamee:12345678"

I used the crumb I got from the wget command, the 4th command.

None of the previous answers worked for me, but mixing some flags i got it working:

JKSERVER="http://localhost:8080"
JKUSER="jenkins_user"
JKPASSWORD="jenkins_password"
JKCRUMB=`wget -q --auth-no-challenge --user $JKUSER --password $JKPASSWORD --output-    document - '$JKSERVER/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'`

curl --user $JKUSER:$JKPASSWORD -I -X POST "$JKSERVER/job/master/build" -H "$JKcrumb"

For me only this way worked:

1.In Jenkins which you are going to trigger need generate for the same user a TOKEN 2.In the same Jenkins you need to create a pipeline job and set a checkbox: This Project is Parameterized and create all variables 2.In the same jenkins set checkbox Trigger Build Remotely and write your TOKEN which you created in the prev step 3.Save it

Now in your Jenkins which will run the script and trigger the remote: (always use -v whith curl,then yo will verbose response and see why it fails)

pipeline { agent any

stages {
    stage('Hello') {
        steps {
            echo 'Hello World'
            script{
                
                  //need cut crumb from response
                  def StringURL = http://yourjenkins:8080/crumbIssuer/api/xml?xpath=concat'('//crumbRequestField,%22:%22,//crumb')'
                  def crumbRes = sh(script: "curl -v GET ${StringURL} --user youruserforremotejenkins:yourpassforremotejenkins", returnStdout: true)
                  echo "Print Full Respose Crumb:${crumbRes} "
                  
                  def response = sh(script: """curl -v -u youruserforremotejenkins:yourpassforremotejenkins -X Post http://yourjenkins:8080/job/TEST_FOLDER_JOB/job/Test_Pipeline_Job/buildWithParameters?token=YOUR_TOKEN -F param1=true -F param2=12345 -F delay=0 -H "${crumbRes}" """, returnStdout: true)
                  
                  echo "Print Response:${response}"   
            }
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top