生成Jenkins Token遇问题:携带Crumb仍报403无效crumb错误
Jenkins生成API Token时Crumb无效导致403的解决办法
我通过Bash脚本调用Jenkins API生成新Token,明明已经成功获取Crumb密钥,但请求被拒绝,返回403 No valid crumb was included in the request错误。
使用的脚本如下:
jenkinsUrl="http://localhost:8080" jenkinsUser="admin" tokename="newTokenName" # generate crumb crumb=$(curl -u $jenkinsUser:$passwordAdmin -s $jenkinsUrl/crumbIssuer/api/json | jq -r '.crumb') echo "Here is the crumb : $crumb" # generate token curl -v -u "$jenkinsUser:$passwordAdmin" \ --data "newTokenName=$tokename" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Jenkins-Crumb: $crumb" \ "$jenkinsUrl/user/$jenkinsUser/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken"
具体错误日志:
* Trying 127.0.0.1:8080... * Connected to localhost (127.0.0.1) port 8080 (#0) * Server auth using Basic with user 'admin' > POST /user/admin/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken HTTP/1.1 > Host: localhost:8080 > Authorization: Basic YWRtaW46ODUxNGM0MzVhY2NlNDY5Zjk4MTgzODMxMzA5MDFmMTA= > User-Agent: curl/7.88.1 > Accept: */* > Content-Type: application/x-www-form-urlencoded > Jenkins-Crumb: 07c445067821590ee913094a53de85c4fbe25504ff1a4434720b5bc28b34ded1 > Content-Length: 25 > < HTTP/1.1 403 Forbidden < Server: Jetty(12.0.16) < Date: Sat, 15 Feb 2025 16:52:41 GMT < X-Content-Type-Options: nosniff < Set-Cookie: JSESSIONID.bd4533c5=node0g0r0hnlxjlc71jvqpve60asrr2.node0; Path=/; HttpOnly < Cache-Control: must-revalidate,no-cache,no-store < Content-Type: text/html;charset=iso-8859-1 < Content-Length: 611 < <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/> <title>Error 403 No valid crumb was included in the request</title> </head> <body><h2>HTTP ERROR 403 No valid crumb was included in the request</h2> <table> <tr><th>URI:</th><td>/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken</td></tr> <tr><th>STATUS:</th><td>403</td></tr> <tr><th>MESSAGE:</th><td>No valid crumb was included in the request</td></tr> <tr><th>SERVLET:</th><td>Stapler</td></tr> </table> <hr/><a href="https://jetty.org/">Powered by Jetty:// 12.0.16</a><hr/> </body> </html> * Connection #0 to host localhost left intact
问题原因
Jenkins的Crumb密钥与用户的Session(JSESSIONID Cookie)绑定,获取Crumb时的Session和提交Token请求时的Session必须一致,否则即使Crumb值正确也会被判定无效。另外部分Jenkins版本可能使用不同的Crumb请求头字段,硬写Jenkins-Crumb可能不兼容。
解决办法
1. 保存并复用Session Cookie
获取Crumb时用curl的-c参数保存Cookie到本地文件,后续请求用-b参数带上该Cookie,确保Session一致。
2. 动态获取Crumb请求头字段
从Crumb Issuer的响应中同时提取crumb和crumbRequestField(即请求头的名称),避免版本差异导致的字段不匹配。
修改后的完整脚本:
jenkinsUrl="http://localhost:8080" jenkinsUser="admin" tokename="newTokenName" cookieFile="/tmp/jenkins_cookie.txt" # 生成Crumb并保存Cookie crumbData=$(curl -u "$jenkinsUser:$passwordAdmin" -s -c "$cookieFile" "$jenkinsUrl/crumbIssuer/api/json") crumb=$(echo "$crumbData" | jq -r '.crumb') crumbRequestField=$(echo "$crumbData" | jq -r '.crumbRequestField') echo "Crumb: $crumb" echo "Crumb请求头字段: $crumbRequestField" # 生成Token,复用Cookie和正确的Crumb头 curl -v -u "$jenkinsUser:$passwordAdmin" \ -b "$cookieFile" \ --data "newTokenName=$tokename" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "$crumbRequestField: $crumb" \ "$jenkinsUrl/user/$jenkinsUser/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken"
额外排查点
- 确认
$passwordAdmin变量已正确赋值,无空值或错误 - 检查Jenkins用户
admin是否拥有User/Configure权限(生成Token需要该权限) - 若Jenkins配置了反向代理,确保代理正确传递Cookie和请求头信息
内容的提问来源于stack exchange,提问作者the star
相关产品推荐
相关产品推荐

