Spinnaker:403请求中未包含有效的crumb

时间:2017-06-23 01:26:36

标签: jenkins spinnaker

我按照以下方式在大三角帆中配置了jenkins并设置了spinnaker管道。

 jenkins:
    # If you are integrating Jenkins, set its location here using the baseUrl
    # field and provide the username/password credentials.
    # You must also enable the "igor" service listed separately.
    #
    # If you have multiple jenkins servers, you will need to list
    # them in an igor-local.yml. See jenkins.masters in config/igor.yml.
    #
    # Note that jenkins is not installed with Spinnaker so you must obtain this
    # on your own if you are interested.
    enabled: ${services.igor.enabled:false}
    defaultMaster:
      name: default
      baseUrl: http://server:8080
      username: spinnaker
      password: password

但是我在尝试运行spinnaker管道时看到了以下错误。

Exception ( Start Jenkins Job ) 403 No valid crumb was included in the request

21 个答案:

答案 0 :(得分:25)

要解决此问题,请取消选中jenkins.com/configureSecurity部分中的“防止跨站点请求伪造攻击”并开始工作。

Prevent Cross Site Request Forgery exploits

答案 1 :(得分:11)

Crumb只是访问令牌。下面是获取面包屑的api

<强> https://jenkins.xxx.xxx.xxx/crumbIssuer/api/json //用您的jenkins网址替换它,并在邮递员或rest-api来电者中进行GET通话。

这将产生如下输出:

{
    "_class": "hudson.security.csrf.DefaultCrumbIssuer",
    "crumb": "ba4742b9d92606f4236456568a",
    "crumbRequestField": "Jenkins-Crumb"
}

以下是与此相关的更多详细信息和链接: How to request for Crumb issuer for jenkins 詹金斯维基页面: https://wiki.jenkins-ci.org/display/jenkins/remote+access+api

如果您通过rest-api呼叫呼叫相同,请查看以下链接,其中说明了如何使用jenkins-crumb呼叫休息呼叫

https://blog.dahanne.net/2016/05/17/how-to-update-a-jenkins-job-posting-config-xml/

示例:

curl -X POST http://anthony:anthony@localhost:8080/jenkins/job/pof/config.xml --data-binary "@config.xml" -data ".crumb=6bbabc426436b72ec35e5ad4a4344687"

答案 2 :(得分:10)

对于新版本的Jenkins,您应遵循以下解决方案:

https://jenkins.io/doc/upgrade-guide/2.176/#upgrading-to-jenkins-lts-2-176-3

升级到Jenkins 2.176.2改进了CSRF保护

SECURITY-626

CSRF令牌(小块)现在仅对它们曾经是Web会话有效 旨在限制攻击者获取它们的影响。剧本 使用/ crumbIssuer / api URL获取面包屑的操作现在将无法 除非脚本保留了网络,否则执行不受CSRF保护的操作 后续请求中的会话ID。脚本可以改用API 令牌,自Jenkins 2.96起不再需要CSRF令牌。

要禁用此改进,可以设置系统属性 hudson.security.csrf.DefaultCrumbIssuer.EXCLUDE_SESSION_ID为true。 或者,您可以安装Strict Crumb Issuer Plugin 提供更多选项来自定义碎屑验证。它允许 从验证条件中排除Web会话ID,而是 例如将其替换为基于时间的到期时间,以实现类似(甚至 更好)对CSRF的保护

就我而言,它帮助安装了Strict Crumb Issuer插件, 重新启动jenkins,并按照供应商网站上的建议对Jenkins的Web界面应用不太严格的策略。

答案 3 :(得分:6)

根据Jenkins Directive 首先,如果版本低于2.176.2,则必须检查您的Jenkins版本,然后根据Jenkins准则,CSRF令牌(小块)现在仅对创建它们的Web会话有效,以限制攻击者获取它们的影响。使用/ crumbIssuer / api URL获取垃圾的脚本现在将无法执行受CSRF保护的操作,除非该脚本在后续请求中保留了Web会话ID。

或者,您可以安装Strict Crumb Issuer插件,该插件提供更多选项来自定义面包屑验证。它允许从验证标准中排除Web会话ID,例如将其替换为基于时间的到期,以提供类似(甚至更好)的CSRF保护。

步骤:

  • 您必须安装名为“ Strict Crumb Issuer”的插件
  • 安装后重新启动jenkins服务
  • 获取“管理Jenkins”->“配置全局安全性”->在CSRF保护下,从下拉列表中选择“严格的碎屑问题”->单击“高级”并取消选中所有内容,但选择“防止突破攻击” “ 选项。 ->应用并保存。
  • 现在运行您的脚本屑脚本。

现在应该可以工作。

Check this image for your reference

答案 4 :(得分:4)

我使用 API令牌作为基本身份验证密码来解决。这是

{{1}}

注意:要在“帐户”图标下创建 API令牌->配置-> API令牌->添加新令牌

答案 5 :(得分:3)

最后,这篇文章帮助我解决了面包屑问题,但仍然使詹金斯免受CSRF攻击。

Solution for no-valid crumb included in the request issue

基本上,我们需要先请求通过身份验证的面包屑,然后再次发出以面包屑作为标头的POST api调用以及身份验证。

这就是我的做法

curl -v -X GET http://jenkins-url:8080/crumbIssuer/api/json --user <username>:<password>

响应为

{
"_class":"hudson.security.csrf.DefaultCrumbIssuer",
"crumb":"0db38413bd7ec9e98974f5213f7ead8b",
"crumbRequestField":"Jenkins-Crumb"
}

然后在其中包含上述面包屑信息的POST api。

curl -X POST http://jenkins-url:8080/job/<job-name>/build --user <username>:<password> -H 'Jenkins-Crumb: 0db38413bd7ec9e98974f5213f7ead8b'

答案 6 :(得分:3)

当我使用jenkins-client库(即com.offbytwo.jenkins)从Java程序创建jenkins作业时,确实收到了相同的“ 403 No有效面包屑未包含在请求中”错误。然后,在下面的代码中,我使用jenkins api令牌代替了密码。现在,此问题已解决。

JenkinsServer jServer = new JenkinsServer(new URI(jenkins_url), jnkn_username, jnkn_password);

我们可以从Jenkins控制台生成API令牌。配置文件>配置> API令牌(添加新令牌)

答案 7 :(得分:2)

  

此解决方案可安全使用

当我们将jenkins更改为可以通过反向代理访问时,就遇到了这个问题。

配置全局安全性”中有一个选项“ 启用代理兼容性”  这有助于解决我的问题。

enter image description here

答案 8 :(得分:2)

由于此问题是在Google中搜索“请求中未包含有效面包屑”时的第一个SO链接,因此我认为值得一提的是,如果您省略/忘记了Authorization HTTP标头或使用了空白的用户名/密码: Screenshot showing error with omitted Authorization HTTP header

仅在传递值时才生成与Authorization标头有关的相关错误消息: Screenshot showing errors related to the Authorization header

是的,在第一个屏幕截图中传递的面包屑实际上是有效的;一切都可以使用正确的用户名/密码进行: Screenshot showing the crumb used earlier is valid

因此,不确定是否是错误,但是“请求中未包含有效碎屑”也可能意味着您不小心忘记了Authorization标头。

Jenkins 2.222.3,Ubuntu Server 20.04,Java运行时1.8.0_252-8u252-b09-1ubuntu1-b09

答案 9 :(得分:1)

我花了很多时间试图解决这个问题。最后,我刚刚安装了此插件https://plugins.jenkins.io/build-token-root/,并为匿名用户启用了构建权限。最后,由于jenkins实例位于VPN后面,并且我正在使用https://smee.io将webhook转发到Jenkins实例,因此并没有真正的意义。此外,Jenkins实例在反向代理后面,因此也选中了“启用代理兼容性”选项,并且在服务器级别的Nginx配置中将“ ignore_invalid_headers”设置设置为off。共享我的解决方案,以防万一其他人也在挣扎。我相信有更好的方法可以做到这一点,但这是一种选择。

请注意,使用此插件,构建URL设置为 buildByToken / build?job = JobName&token = TokenValue ,并且令牌在作业设置中生成。

这是Jenkins 2.235.2中的版本,它没有禁用CSRF的选项。

答案 10 :(得分:1)

您需要一个 2 步过程,首先从服务器获取面包屑,然后使用它。 我正在使用这个 bash 脚本和 curl:

#!/bin/bash
# buildme.sh    Runs a build Jenkins build job that requires a crumb
# e.g.
# $ ./buildme.sh 'builderdude:monkey123' 'awesomebuildjob' 'http://paton.example.com:8080'
# Replace with your admin credentials, build job name and Jenkins URL
#
# More background:
# https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained
USERPASSWORD=$1
JOB=$2
SERVER=$3
# File where web session cookie is saved
COOKIEJAR="$(mktemp)"
CRUMB=$(curl -f -u "$USERPASSWORD" --cookie-jar "$COOKIEJAR" "$SERVER/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")
status=$?
if [[ $status -eq 0 ]] ; then
  curl -f -X POST -u "$USERPASSWORD" --cookie "$COOKIEJAR" -H "$CRUMB" "$SERVER"/job/"$JOB"/build
  status=$?
fi
rm "$COOKIEJAR"
exit $status

以下是使用您需要的参数执行此脚本的示例:

$ ./buildme.sh 'builderdude:monkey123' 'awesomebuildjob' 'http://paton.example.com:8080'

如果其中一个 curl 命令因任何原因失败,此脚本将返回错误代码。

更多详情请见cloudbees

答案 11 :(得分:0)

要让Java代码访问Jenkins API,我会建议。

@Santhosh(https://stackoverflow.com/a/60221003/5940655)的答案确实解决了这个问题,其中包括将密码更改为令牌,但是据我所知, 现在令牌是一种传统方式。 因此,我尝试了另一种方法,并在Java代码中找到了解决方案。

这是我的方法。 在我的Java代码中,我使用“ com.offbytwo.jenkins ,而我使用的类是“ JenkinsServer ”。

我的问题是在 jenkins 中创建工作,因为出现错误:“ 403请求中未包含有效碎屑

然后我找到了一个名为 crumbFlag 的布尔参数,并在其上传递了“ true ”,一切正常。

我的代码是这样的:

jenkins.createJob(job.getName(), config);

然后,我为此进行了更改,就像一个魅力:

jenkins.createJob(job.getName(), config, true);

此参数几乎包含在此软件包的所有方法中,例如:

  • createJob(字符串jobName,字符串jobXml,布尔值crumbFlag)
  • updateJob(字符串jobName,字符串jobXml,布尔值crumbFlag)
  • renameJob(字符串oldJobName,字符串newJobName,布尔值crumbFlag)
  • 其他。

代码内的技术文档为:

@param crumbFlag true添加 crumbIssuer * false否则。

我知道,如果您为此参数传递“ true ”,它将自动发出面包屑。

好吧,官方文档提供了有关详细信息的信息,如果您愿意,请在此处查看:

https://javadoc.io/doc/com.offbytwo.jenkins/jenkins-client/latest/com/offbytwo/jenkins/JenkinsServer.html

答案 12 :(得分:0)

首先通过转到用户-> API令牌->添加新令牌来创建用户API令牌。

然后使用以下脚本进行触发。

import jenkins,requests
job_name='sleep_job'
jenkins_url = "http://10.10.10.294:8080"
auth = ("jenkins","1143e7efc9371dde2e4f312345bec")
request_url = "{0:s}/job/{1:s}/buildWithParameters".format(jenkins_url, 
job_name, )
crumb_data = requests.get("{0:s}/crumbIssuer/api/json".format(jenkins_url), 
auth=auth, ).json()
headers = {'Jenkins-Crumb': crumb_data['crumb']}
jenkins_job_params={}
jenkins_job_params['NODE_NAME']='10_10_1_29'
jenkins_job_params['SLEEP_TIME']='1h'
response = requests.post(request_url, data=jenkins_job_params, auth=auth, )
response.raise_for_status()

答案 13 :(得分:0)

guide说明了如何生成Jenkins碎屑,保存cookie以及在随后需要身份验证的请求中使用碎屑和保存的cookie。对于V2.176.2之后的Jenkins,这是必须的。

答案 14 :(得分:0)

我在尝试使用 GitHub Pull Request Builder 插件设置 GitHub 项目时遇到了同样的问题

  • 这是我从 Jenkins 服务器获得的响应示例

enter image description here

  • 回复内容

enter image description here

  • 出现问题是因为我的有效负载网址/ 末尾缺少正斜杠。

  • 在url末尾添加正斜杠即可解决问题

  • 您的有效负载网址应如下所示 https://jenkins.host.com/ghprbhook/

  • 添加正斜杠后的示例

enter image description here

enter image description here

答案 15 :(得分:0)

这是我对此问题的解决方案(git hook 在反向代理后面启动 jenkins 作业)

#从第一次调用中获取 CRUMB 并将 sessionid 存储在 cookie jar 中:

CRUMB=$(/usr/bin/curl --cookie-jar ./cookie -sX GET https://******.net/crumbIssuer/api/json|cut -d'"' -f8)

#启动作业:

/usr/bin/curl --cookie ./cookie -X POST https://******.net/job/PROJECTNAME/build -H "Jenkins-Crumb: $CRUMB"

答案 16 :(得分:0)

前往Manage Jenkins =>配置全局安全性。

然后取消选中“ 防止跨站点请求伪造漏洞

答案 17 :(得分:0)

对我来说,解决方案是传递 X-Forwarded-HostX-Forwarded-Port 标头 按照手册的 reverse-proxy-configuration-troubleshooting 章节中的建议。

HaProxy 配置,在 frontend 部分内:

http-request set-header  X-Forwarded-Host  %[hdr(host)]
http-request set-header  X-Forwarded-Port  %[dst_port]

答案 18 :(得分:0)

我也遇到了类似的问题,我使用的是密码而不是 token。 更新后解决了我的问题,无需取消选中任何内容并使其不安全。以下是我让 jenkins CLI 工作的完整步骤-

步骤 -1:- 准备 ENV 变量

export JENKINS_URL=http://localhost:8080/
export JENKINS_USER=admin
export JENKINS_PASSWORD=b7f04f4efe5ee117912a1.....
export JENKINS_CRUMB=f360....
export FOLDER=test

获得令牌作为- How to get the API Token for Jenkins

获得 CRUMB 作为- http://localhost:8080/crumbIssuer/api/json

step-2 :- 准备 XML 文件,文件名 creds.xml

<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>      
  <scope>GLOBAL</scope>                  
  <id>TEST-CLI</id>            
  <username>test</username>    
  <password>test123</password>
  <description>this secret if created confirms that jenkins-cli is working</description>        
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>

第 3 步:- 使用 curl 发布

curl -X POST -u $JENKINS_USER:$JENKINS_PASSWORD -H "Jenkins-Crumb:${JENKINS_CRUMB}" -H 'content-type:application/xml' -d @creds.xml "$JENKINS_URL/job/$FOLDER/credentials/store/folder/domain/_/createCredentials"

答案 19 :(得分:-1)

我正在使用带有Nignx的反向代理。更改了“配置全局安全性”中的“启用代理兼容性”的jenkins选项,此问题已解决。

答案 20 :(得分:-3)

我遇到了同样的问题。我只刷新了浏览器,重新登录Jenkins,执行相同的过程,一切正常。