No valid crumb was included in the request 问题定位与解决
背景
测试环境Jenkins版本进行了升级,发现代码中直接使用http调用Jenkins REST API的方法失效了,这边是除了GET以外其他的操作类的接口失效了,都是同样的错误,No valid crumb was included in the request。
百度的结果
搜索了具体的错误信息,发现都是一样的,就是说把Jenkins的CSRF给关闭了,但是我在Jenkins上面没有找到关闭CSRF的入口。就像下面这张图。
然后百度得知,Jenkins高版本关闭了页面上面取消CSRF防护的入口,本来也不推荐关闭。就想到失效的原因应该是之前的Jenkins一直没有打开CSRF防护,所以接口都是可以调用的。
解决
- 方法一
这边我当时是想,既然说没有这个crumb,那我就在请求的时候生成这个crumb头,然后加上再去调用接口不就好了。但是当我加上这个头之后,还是报同样的错误,很头疼。方法一GG。
下面是我之前写的代码,大家也可以参考下。
定义了一个crumb的实体对象。
// crumb头实体对象
@Data
private static class CrumbEntity implements Serializable {private String _class;private String crumb;private String crumbRequestField;
}
具体获取crumb头信息的方法。这边能够获取到crumb请求头,然后我也将这个头信息也加到了请求上,还是报错。
/*** 单独提取的一个公共方法** @param url 请求地址* @param httpRequest 请求方法对象* @return*/
private String customHttpMsg(String url, HttpRequest httpRequest) throws URISyntaxException, IOException {URI uri = new URI(url);HttpHost host = new HttpHost(uri.getHost(), uri.getPort());CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()),new UsernamePasswordCredentials(JENKINS_USERNAME, JENKINS_PASSWORD));AuthCache authCache = new BasicAuthCache();BasicScheme basicScheme = new BasicScheme();authCache.put(host,basicScheme);try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build()) {HttpClientContext httpClientContext = HttpClientContext.create();httpClientContext.setAuthCache(authCache);CloseableHttpResponse response = httpClient.execute(host, httpRequest, httpClientContext);return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);}
}// 获取crumb头
private CrumbEntity getCrumb() throws IOException, URISyntaxException {String url = JENKINS_URL + "/crumbIssuer/api/json";HttpGet httpGet = new HttpGet(url);String res = customHttpMsg(url, httpGet);return JSON.parseObject(res, CrumbEntity.class);
}// 测试获取crumb头
@Test
public void testGetCrumb() throws IOException, URISyntaxException {CrumbEntity crumb = getCrumb();log.info("crumb is {}", crumb);
}// 测试方法调用前添加crumb头
// 但是测试无效
@Test
public void testAddCrumb() throws IOException, URISyntaxException {String url = JENKINS_URL+"/createItem/api/json?name="+JENKINS_PROJECT_NAME;HttpPost httpPost = new HttpPost(url);CrumbEntity crumb = getCrumb();// 添加crumb头httpPost.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));httpPost.setEntity(new StringEntity(JENKINS_PROJECT_XML, ContentType.create("text/xml", "utf-8")));String res = customHttpMsg(url, httpPost);log.info("res is {}", res);
}
- 方法二
接口调用不了了,很急,就想到这个日志应该是Jenkins打印出来的,然后就去下载了Jenkins的源码,全局搜索了这个错误日志,果然搜索到了,还有一段解释。
这段代码在core/src/main/java/hudson/security/csrf/CrumbFilter.java里面,这个类是一个过滤器,方法中具体的逻辑是判断crumb头是否合法,然后再进行放行操作。
这边到具体抛出问题的位置,然后看了下具体的日志,日志里面是说使用这种token来代替,然后打开后面的链接。贴一下链接地址:https://jenkins.io/redirect/crumb-cannot-be-used-for-script
翻译大概是,CSRF的这个crumb头目前仅仅是对创建他们的Web会话有效,以限制攻击者的攻击。就是我们通过这个/crumbIssuer/api 获取到的crumb,除非是保存了Web会话信息,不然是无法调用CSRF保护的接口的。或者说使用API token,这种方式是不需要额外添加crumb头的。
这么看,大概有两种方法可以解决这个问题。第一种是调用接口时,把会话信息带着,实现感觉有点复杂,没做。第二种,就是使用API token的方式,然后这个token怎么添加呢?
添加token
添加这个token很简单,我这边也简单整理了下。
选择Jenkins当前用户。选择配置,添加用户对应的一个token信息。
这块,生成的token需要自己保存下来,关于token的好处Jenkins也进行了说明,大家可以看看。我自己认为可能是为了安全吧,比如我们对外提供一个token而不是密码,当我们想要收回这个操作权限的时候,我们只需要把token删除掉就好了,而不需要去修改密码。
OK,添加完成token,然后再去调用请求,发现可以通过,这个问题也算解决了。
// 推荐使用token
String JENKINS_TOKEN = "112c7c08043e02449e7fb97d253a657ede";/*** 单独提取的一个公共方法** @param url 请求地址* @param httpRequest 请求方法对象* @return*/
private String customHttpMsg(String url, HttpRequest httpRequest) throws URISyntaxException, IOException {URI uri = new URI(url);HttpHost host = new HttpHost(uri.getHost(), uri.getPort());CredentialsProvider credentialsProvider = new BasicCredentialsProvider();// 注意这边 我把密码换成了tokencredentialsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()),new UsernamePasswordCredentials(JENKINS_USERNAME, JENKINS_TOKEN));AuthCache authCache = new BasicAuthCache();BasicScheme basicScheme = new BasicScheme();authCache.put(host,basicScheme);try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build()) {HttpClientContext httpClientContext = HttpClientContext.create();httpClientContext.setAuthCache(authCache);CloseableHttpResponse response = httpClient.execute(host, httpRequest, httpClientContext);return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);}
}// 使用token 调用OK
@Test
public void testAddWithToken() throws IOException, URISyntaxException {// http://192.168.1.107:8081/jenkins/createItem/api/json?name=testString url = JENKINS_URL+"/createItem/api/json?name="+JENKINS_PROJECT_NAME;HttpPost httpPost = new HttpPost(url);httpPost.setEntity(new StringEntity(JENKINS_PROJECT_XML, ContentType.create("text/xml", "utf-8")));String res = customHttpMsg(url, httpPost);log.info("res is {}", res);
}
项目地址:https://github.com/yzh19961031/blogDemo/tree/master/jenkins_api
所有的代码都在代码仓上面,大家有兴趣或者有疑问可以去看看。
No valid crumb was included in the request 问题定位与解决相关推荐
- [Jenkins]Error:403 No valid crumb was included in the request
错误备忘 配置 jenkins 的时候,一直报这个错,是因为 jenkins 默认安全设置里面开启了 防止款站点请求伪造. 方法: 取消勾选这一项,就可以成功集成了 位置: Jenkins > ...
- jenkinsapi操作Jenkins,提示:No valid crumb was included in the request
# coding:utf-8from jenkinsapi.jenkins import Jenkins# 实例化Jenkins对象,传入地址+账号+密码 j = Jenkins("http ...
- jenkins 出现“Error 403 No valid crumb was included in the request ”的解决方案
背景介绍 开发的jenkins job 在local的 一台windows 上,而我们测试的jenkins job 在azure 上的一台windows server 2012 上.由于 azure上 ...
- No valid crumb was included in the request
jenkins curl 报错 No valid crumb was included in the request, 由于之前用curl来获取jenkins job的运行状态,如下 curl -k ...
- Error 403 No valid crumb was included in the request 报错解决 容器化jenkins关闭CSRF
现象 gitlab 连接 安装在容器中的jenkins时,如果使用的是高版本的 jenkins ,会出现403错误,Error 403 No valid crumb was included in t ...
- 解决Error:403 No valid crumb was included in the request
Jenkins错误备忘:Error:403 No valid crumb was included in the request 在Jenkins上创建流水线后不能save,报这个错. 解决办法: 登 ...
- 码云Gitee WebHook Jenkins 403 err:No valid crumb was included in the request
解决Gitee WebHook触发Jenkins 403错误,我的Jenkins版本为2.256,没有网上一般提到的取消勾选框 现象:Jenkins配置远程触发器,get触发正常 post报403,g ...
- 【笔记】Jenkins- 解决 “Error 403 No valid crumb was included in the request“
目录 问题 解决办法(亲测) 问题 HTTP ERROR 403 No valid crumb was included in the request 解决办法(亲测) Dashboard -> ...
- HTTP ERROR 403 No valid crumb was included in the request ~jenkins 太高的版本错误。降低版本
HTTP ERROR 403 No valid crumb was included in the request URI: /buildByToken/build STATUS: 403 MESSA ...
最新文章
- Nginx解决PATH_INFO新解决办法
- nginx启动不了_nginx 变量与监控
- Chapter 1 First Sight——25
- 图像风格迁移cvpr2020_CVPR 2020 | 浙大李俊成:用无监督强化学习方法来获得迁移能力...
- 由汉诺塔引起的对递归的思考
- numpy中int类型与python中的int
- 流行趋势:大背景图片在网页设计的20个精彩应用
- 【优化预测】基于matlab灰狼算法优化BP神经网络预测【含Matlab源码 1729期】
- 计算机word的常用功能技巧,10个Word操作神技巧,看看你会多少?
- 计算机概论二进制加法,计算机科学概论二进制
- 快手,抖音,美拍打造个人IP精准引流!
- 如何创建一个原始Mac OS镜像
- 2018 新年快乐 万事如意
- ZOJ1516HDU1507(二分图匹配)
- uni-app支付宝小程序map地图组件基础操作+画多边形+打点连线
- pytorch dataset自定义_PyTorch 系列 | 数据加载和预处理教程
- 通过mtd读写flash_NOR Flash读写原理及驱动
- Microsoft Office Word 选中图片锐化 以及 所有图片锐化的宏代码
- 电力电子技术简答题及其答案
- 利用Python实现有道翻译的功能