詹金斯订书机的请求失败,没有有效的面包屑 [英] Jenkins stapler requests fail with no valid crumb

查看:133
本文介绍了詹金斯订书机的请求失败,没有有效的面包屑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Jenkins插件,现在我正停留在尝试使用

I'm working on a Jenkins plugin and I'm now stuck at a point where I'm trying to get the return value of a method using a JavaScript proxy as described here.

我只是想调用此kotlin方法:

I simply want to call this kotlin method:

@JavaScriptMethod
fun getMonitoredJobsAsJSON(): JSONArray = toJSON(getObjectMapper().writeValueAsString(getMonitoredJobs())) as JSONArray

从果冻脚本中使用以下方法:

From the jelly script using this:

<script>
  var board = <st:bind value="${it}"/>

  board.getMonitoredJobsAsJSON(function(data) {
   //
  })
</script>

当我在Jenkins服务器上禁用CSRF保护时,此方法实际上起作用,但是我显然不想这样做.启用CSRF保护后,我总是会发现没有有效的碎屑403错误:

This actually works when I disable CSRF protection on the Jenkins server but I obviously don't want to do that. With CSRF protection on I always get a no valid crumb found 403 error:

POST http://localhost:8080/$stapler/bound/36dc05fc-c12d-4182-a008-60bcf5c49307/getMonitoredJobsAsJSON 403 (No valid crumb was included in the request)

我知道如何从crumbIssuer端点检索碎屑以便与Jenkins rest api进行交互,但是我几乎没有发现有关如何使其适用于插件中的装订器请求的资源.

I know how to retrieve crumbs from the crumbIssuer end point for interacting with the Jenkins rest api but I've found virtually no resources on how to make it work for stapler requests in plugins.

此外,当我检查请求时,实际上在请求中设置了一个屑头:

Also, when I inspect the requests, a crumb header is actually set in the request:

在此先感谢您的帮助.

推荐答案

几周后,我终于找到了解决方案.

Weeks later, I finally found a solution to this.

问题是由于某种原因,默认情况下附加到请求的面包屑标头的名称实际上是错误的.如我问题中的屏幕快照所示,它是Crumb,但对于较旧版本的Jenkins,实际上应该为Jenkins-Crumb.crumb.

The problem was that for some reason, the name of the crumb header appended to the requests by default is actually wrong. It's Crumb as shown in the screenshot in my question, but it actually should be Jenkins-Crumb or .crumb for older versions of Jenkins.

我要做的是找到一种方法,当页面最初加载时,从服务器中检索面包屑和正确的标头名称,然后使用正确的名称将此面包屑标头附加到任何后续标头中xhr请求.

What I did was to find a way to retrieve a crumb and the correct header name from the server when the page is loading initially, and then append this crumb header using the correct name to any subsequent xhr requests.

我为面包屑定义了一个实体:

I defined an entity for the crumbs:

class RemoteRequestCrumb {
    @JsonIgnore private val crumbIssuer: CrumbIssuer? = Jenkins.getInstance()?.getCrumbIssuer()
    val fieldName: String? = crumbIssuer?.crumbRequestField
    val crumbValue: String? = crumbIssuer?.crumb
}

然后将此实体作为属性添加到插件:

And then add this entity to the plugin as an attribute:

fun getRemoteRequestCrumb(): JSONObject = toJSON(
    SerializationUtils.getObjectWriter().writeValueAsString(RemoteRequestCrumb())
) as JSONObject

现在,您可以像其他任何插件属性:${it.getRemoteRequestCrumb()}一样,从果冻脚本中请求面包屑数据.

Now you can request the crumb data from a jelly script as with any other plugin attribute: ${it.getRemoteRequestCrumb()}.

最后一步实际上是向所有XHR请求附加正确的标头:

The last step is actually appending the correct header to all XHR requests:

appendCrumbHeaderToAllRequests: function () {
  let crumb = JSON.parse(this.remoteRequestCrumb);
  let open = XMLHttpRequest.prototype.open;

  XMLHttpRequest.prototype.open = function() {
    let mutatedPrototype = open.apply(this, arguments);
    this.setRequestHeader(crumb.fieldName, crumb.crumbValue);
    return mutatedPrototype;
  }
}

这篇关于詹金斯订书机的请求失败,没有有效的面包屑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆