【发布时间】:2020-10-08 21:26:08
【问题描述】:
我正在开发一个 Jenkins 插件,该插件在使用 Jelly 和 Stapler 请求生成的页面上使用 HTML 表单。升级到更新版本的 Jenkins 后,此表单中的 POST 停止工作,给我来自 Jenkins 的以下 403 错误:
HTTP ERROR 403 No valid crumb was included in the request
URI: /job/Watchr_Sandbox/performanceReports/
STATUS: 403
MESSAGE: No valid crumb was included in the request
SERVLET: Stapler
我对最近的CSRF security improvement to Jenkins 做了很多研究,这似乎是这个问题的根源,并且我已经阅读了很多其他 Stack Overflow 解决方案来解决这个问题 (this one seems to be closest),但是我没有找到任何与我的情况完全一样的例子。
基本上,我希望表单的 POST 包含 Jenkins 碎屑信息。现在,我正试图通过将 crumb 信息包含为隐藏的表单值来解决这个问题,但我不知道我是否以正确的方式获取 Jenkins crumb,或者我是否正确地解决了这个问题。
.jelly 文件
<j:jelly xmlns:j="jelly:core" xmlns:g="glide" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:test="/lib/hudson/test" xmlns:f="/lib/form" xmlns:i="jelly:fmt" xmlns:RP="jelly:RP">
<l:layout title="Performance Reports">
<st:include page="sidepanel.jelly" it="${it.getOwner()}" />
<l:main-panel>
<j:out value="${it.createHtml()}"/>
</l:main-panel>
</l:layout>
</j:jelly>
Java 代码
import org.kohsuke.stapler.CrumbIssuer;
import org.kohsuke.stapler.Stapler;
import hudson.Functions;
public String createHtml() {
StringBuilder sb = new StringBuilder();
String crumb = Functions.getCrumb(Stapler.getCurrentRequest());
String crumbRequestField = Functions.getCrumbRequestField();
sb.append("<form method=\"post\" autocomplete=\"off\"");
// ...
sb.append("<input type=\"hidden\"");
sb.append(" id=\"crumb\"");
sb.append(" name=\"crumb\"");
sb.append(" value=\"").append(crumb).append("\"");
sb.append("/>");
sb.append("<input type=\"hidden\"");
sb.append(" id=\"crumbRequestField\"");
sb.append(" name=\"crumbRequestField\"");
sb.append(" value=\"").append(crumbRequestField).append("\"");
sb.append("/>");
// ...
sb.append("</form>");
return sb.toString();
}
【问题讨论】: