Jenkins" Trigger远程构建" > "身份验证令牌"期权缺失

时间:2017-03-15 17:51:17

标签: jenkins

我刚刚在Nginx的反向代理后面设置Jenkins(最新版本为2.5),以便我可以通过HTTPS访问它。

它正在工作,但是我的Multibranch Pipeline作业不再具有"触发器远程构建"主配置中的选项。我不认为我改变了任何其他配置。任何想法发生了什么以及如何取回它?

这是我想要的东西:

Screenshot of what I want back

6 个答案:

答案 0 :(得分:19)

经过一段时间的搜索,我觉得我能够有信心地回答我自己的问题。

我认为答案在于安全设置。身份验证令牌的目的是允许未经授权的用户(开发人员)在没有Jenkins登录权限的情况下触发构建(请参阅https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clientshttps://wiki.jenkins-ci.org/display/JENKINS/Quick+and+Simple+Security)。

因此,如果您使用基于矩阵的安全性(在"配置全局安全性">>授权),那么"触发器远程构建"选项将消失,因为假设您将使用Jenkins用户帐户验证请求。

为了做到这一点,您可以使用用户名/密码(甚至更好的用户名/ API令牌)发出HTTP请求:

curl -X POST "https://username:api-token@JENKINS_URL/job/Example/build"

答案 1 :(得分:12)

声明

  

在阅读这个答案之前,你必须知道我只是在这个答案中积累了所有有用的信息,我已经在stackoverflow中找到了所有这些信息,所有的信息应该是那些做过实际研究的人。

我将链接的内容从此comment移动到stackoverflow,只是为了保留deadlink。

信息

我的工作名称是Football。我还建议你创建一个专用的jenkins用户和密码,而不是像我在这个例子中使用的admin:admin。我的jenkins GUI URL是http://192.168.99.20:8080,因为我在流浪。

创建工作

  1. http://192.168.99.20:8080地址登录jenkins。
  2. 创建一个"自由风格"项目命名为"足球"。
  3. 打开它的配置。
  4. 转到"构建触发器"部分。
  5. 勾选"触发器远程构建(例如,从脚本)"选项只是为了记下那里写的文字并再次取消它。文字为Use the following URL to trigger build remotely: JENKINS_URL/job/Football/build?token=TOKEN_NAME or /buildWithParameters?token=TOKEN_NAME. Optionally append &cause=Cause+Text to provide text that will be included in the recorded build cause..
  6. 保存并退出。
  7. 获取API用户和令牌

    1. http://192.168.99.20:8080地址登录jenkins。
    2. 点击页面右侧的用户名(我的是管理员)。
    3. 选择"配置"选项将带您进入http://192.168.99.20:8080/user/admin/configure页面。
    4. In" API令牌"部分点击"显示API令牌"按钮。
    5. 注意"用户ID"和" API令牌"稍后在你的curl命令中使用。例如admin:85703fb68927f04968630e192e4927cb
    6. 获得面包屑

      有关详细信息,请访问远程访问API页面。

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

      这会给你Jenkins-Crumb:44e7033af70da95a47403c3bed5c10f8之类的东西。如果没有crumb信息,运行curl命令将导致示例错误,例如HTTP/1.1 403 ForbiddenError 403 No valid crumb was included in the request

      测试

      $ curl -I -X POST http://admin:85703fb68927f04968630e192e4927cb@192.168.99.20:8080/job/Football/build -H "Jenkins-Crumb:44e7033af70da95a47403c3bed5c10f8"
      HTTP/1.1 201 Created
      Date: Fri, 02 Jun 2017 06:17:51 GMT
      X-Content-Type-Options: nosniff
      Location: http://192.168.99.20:8080/queue/item/17/
      Content-Length: 0
      Server: Jetty(9.2.z-SNAPSHOT)
      

      Original link

      除上述信息外,我还发现了如何从answer

      获取cli的Jenkins-Crumb
      CRUMB=$(curl -s 'http://USER:TOKEN@localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
      

答案 2 :(得分:2)

同意。单击右上角显示的用户名时,可以找到API令牌。然后去配置并单击Show API Token。

答案 3 :(得分:1)

有一个适用于1.565.3和更新版本的Jenkins插件可以绕过基于矩阵的身份验证来触发构建作业。我在Emil Dragu对JENKINS-17764(涵盖这一特定问题)的评论中发现了这一点:

安装Build Token Root Plugin,然后将URL中的上半部分更改为较低的等效项(呈现为列表以使其更容易看到):

  • job/ 项目名 /build?token= 测试
  • buildByToken/build?job= 项目名 &token= 测试

您仍然可以传递一个可选的cause参数。

答案 4 :(得分:0)

如果您希望通过编程获得相同的信息,则可以查看Programmatically retrieve Jenkins REST API Token

然后您可以使用此令牌来验证其他Jenkins API的身份。

答案 5 :(得分:0)

我写了这个python脚本来提交工作。这也允许将文件上传到作业。

import os
import json
import requests
from glob import glob
from getpass import getpass

AUTH = (
    os.environ.get('JENKIN_USER') or input('Jenkin username: '),
    os.environ.get('JENKIN_PASSWORD') or getpass('Jenkin password: ')
)
TOKEN = os.environ.get('JENKIN_TOKEN') or input('Jenkin job token: ')
JENKIN_DOMAIN = 'https://jenkins'
REASON = 'Batch jenkin job'
JOB_URL = f'{JENKIN_DOMAIN}/view/some-job-url'
CRUM_ISSUER = f'{JENKIN_DOMAIN}/crumbIssuer/api/json'


session = requests.Session()

def get_crumb(auth=AUTH):
    return session.get(CRUM_ISSUER, auth=auth).json()


def build_job(job_url, params=None, files=None, token=TOKEN, cause=REASON,
              auth=AUTH):
    crum = get_crumb()
    payload = {}
    if params:
        job_url = f'{job_url}/buildWithParameters'
        parameter = []
        if files:
            for key in files:
                parameter.append({"name": key, "file": key})
        for key, value in params.items():
            parameter.append({"name": key, "value": str(value)})
        payload.update(params)
        payload['json'] = json.dumps({
            'parameter': parameter,
            'statusCode': "303",
            'redirectTo': '.'
        })
    else:
        job_url = f'{job_url}/build'

    r = session.post(
        job_url,
        data=payload,
        files=files,
        params={"token": token, "cause": cause, crum['crumbRequestField']: crum['crumb']},
        auth=auth,
        headers={crum['crumbRequestField']: crum['crumb']}
    )
    return r


if __name__ == '__main__':
    # Build job
    build_job(JOB_URL, params={
        'DO_SOMETHING': 'true', "DO_SOMETHING_ELSE"
    })

    # Build job with file upload
    build_job(JOB_URL, params={'NO_HEADER': 'true'}, files={'UPLOAD_FILE_FIELD': f})