33

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.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
JamesE
  • 3,833
  • 9
  • 44
  • 82
  • Possible duplicate of [Jenkins REST API Create job](https://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job) – kenorb Oct 19 '17 at 10:30

8 Answers8

38

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
decocijo
  • 908
  • 7
  • 19
  • How to pass this from bitbucket-webhook? https://stackoverflow.com/questions/56416925/how-to-pass-crumb-info-via-bitbucket-hook-to-jenkins – Mithun Shreevatsa Jun 03 '19 at 15:28
22

The correct format is as follows:

curl -H ".crumb:xxxxxxxxxxxxxxxxxxxxxx"
SuperStar518
  • 2,814
  • 2
  • 20
  • 35
JamesE
  • 3,833
  • 9
  • 44
  • 82
  • How does this differ from what you ran in your question? I'm running into the same issue and can't figure out why it's rejecting the crumb, and it seems to be exactly the way you describe here. – Jesse Apr 03 '15 at 20:43
  • 4
    Okay, figured out my issue: if you generate crumb under a username (which may be required depending on how Jenkins security is configured), any further requests must also include those credentials, and vice versa. Somehow I missed this. – Jesse Apr 03 '15 at 21:57
  • 3
    Note if you grab the crumb from a different "browser" like wget or a different url like localhost via directip / dns / etc the crumb will be different, so don't expect to get the crumb from something via wget and then use it in curl. – sjakubowski May 04 '16 at 21:09
  • 10
    As of Feb 2017, with Jenkins 2.32.1 in Windows the request header key is **not** `.crumb` but instead `Jenkins-Crumb`. Make sure to check that before. The safest option is requesting the crumb from `/crumbIssuer/api/xml` and taking it from the `crumbRequestField` – Roberto S. Feb 06 '17 at 21:09
  • 1
    Example related to @RobertoS.'s comment can be found here. [Running jenkins jobs via command line](http://www.inanzzz.com/index.php/post/jnrg/running-jenkins-build-via-command-line) – BentCoder Jun 04 '17 at 12:27
12

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

Prateek Kapoor
  • 947
  • 9
  • 18
4

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'
"""
Pier A
  • 151
  • 1
  • 4
  • 2
    This was the only solution that worked for me. What it actually says is that you have to be in the same session when you apply the crumb as the one you requested the crumb with. – Rob Juurlink Apr 02 '20 at 22:47
  • What is jenkins_referer header? I see it being used, but I don't see it being set. – grayaii Jan 24 '23 at 14:02
3

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.

shizhen
  • 12,251
  • 9
  • 52
  • 88
MOHAMED RAIYAN
  • 101
  • 1
  • 3
2

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.

RaamEE
  • 3,017
  • 4
  • 33
  • 53
0

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"
0

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}"   
            }
            }
        }
    }
}