Jenkins Docker容器 - 403没有有效的crumb包含在请求中

时间:2018-01-03 23:42:50

标签: jenkins kubernetes

我正在设置我的Jenkins服务器,并且在Web界面中的简单请求中,如创建文件夹,管道,作业等,我会定期收到以下错误:

HTTP ERROR 403
Problem accessing /job/Mgmt/createItem. Reason:

    No valid crumb was included in the request

服务器使用Jenkins / Jenkins容器,由Kubernetes在使用kops创建的AWS上的集群上编排。它位于ELB课程的后面。

为什么我会遇到这个?我认为面包屑是为了打击某些CSRF请求,但我所做的只是使用Jenkins网络界面。

3 个答案:

答案 0 :(得分:2)

启用代理兼容性可能有助于解决此问题。 转到设置 - >安全 - > 在CSRF保护部分

中启用代理兼容性
  

某些HTTP代理会过滤掉默认crumb颁发者用来计算nonce值的信息。如果HTTP代理位于浏览器客户端和Jenkins服务器之间,并且在向Jenkins提交表单时收到403响应,则选中此选项可能会有所帮助。使用此选项可以更容易伪造nonce值。

答案 1 :(得分:1)

经过几个小时的努力,我得以使其与curl一起使用:

export JENKINS_URL=http://localhost
export JENKINS_USER=user
export JENKINS_TOKEN=mytoken
export COOKIE_JAR=/tmp/cookies

JENKINS_CRUMB=$(curl --silent --cookie-jar $COOKIE_JAR $JENKINS_URL'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' -u $JENKINS_USER:$JENKINS_TOKEN)

echo $JENKINS_CRUMB

curl --cookie $COOKIE_JAR $JENKINS_URL/createItem?name=yourJob --data-binary @jenkins/config.xml -H $JENKINS_CRUMB -H "Content-Type:text/xml" -u $JENKINS_USER:$JENKINS_TOKEN -v

答案 2 :(得分:0)

在调用http://JENKINS_SERVER:JENKINS_PORT/JENKINS_PREFIX/crumbIssuer/api/json时,您会收到标头(“ Set-Cookie”)以设置JSESSIONID,因此您必须在即将发出的请求中提供该标头,

原因是jenkins以此方式测试有效的面包屑:将您在请求中发送的面包屑与它在服务器端使用会话ID生成的面包屑进行比较,

您可以在詹金斯代码中看到它:向下滚动到方法:

public boolean validateCrumb(ServletRequest request, String salt, String crumb)

这意味着您必须将会话添加到下一个请求中(提取面包屑之后)!

因此,curl --cookie必须按照ThiagoAlves在其解决方案中所述

我使用Java,所以我使用了下一个测试器(首选HTTPClient,但我想要一个仅Java的简单示例):

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;


public class JobRunner
{
    String jenkinsUser = "tester";
    String jenkinsPassword = "1234"; // password or API token
    String jenkinsServer = "localhost";
    String jenkinsPort = "8080";
    String jenkinsPrefix = "/jenkins";

    String jSession = null;
    String crumb = null;
    HttpURLConnection connection = null;
    String responseBody = "";

    public void openConnection(String requestMethod, String relativeURL) throws Exception
    {       
        // prepare the authentication string
        String authenticationString = jenkinsUser + ":" + jenkinsPassword;
        String encodedAuthenticationString = Base64.getEncoder().encodeToString(authenticationString.getBytes("utf-8"));

        // construct the url and open a connection to it
        URL url = new URL("http://" + jenkinsServer + ":" + jenkinsPort + jenkinsPrefix + relativeURL);
        connection = (HttpURLConnection) url.openConnection();

        // set the login info as a http header
        connection.setRequestProperty("Authorization", "Basic " + encodedAuthenticationString);

        // set the request method
        connection.setRequestMethod(requestMethod);
    }

    public void readResponse() throws Exception
    {
        // get response body and set it in the body member
        int responseCode = connection.getResponseCode();
        switch (responseCode)
        {
        case 401:
                System.out.println("server returned 401 response code - make sure your user/password are correct");
            break;

        case 404:
            System.out.println("server returned 404 response code - make sure your url is correct");
        break;

        case 201:
        case 200:
            System.out.println("server returned " + responseCode + " response code");
            InputStream responseBodyContent = connection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(responseBodyContent));
            String currentLine;
            while ((currentLine = bufferedReader.readLine()) != null)
            {
                responseBody = responseBody + currentLine + "\n";
            }
        break;

        default:
            System.out.println("server returned error response code: " + responseCode);
            break;
        }
    }

    public void setSessionCookie() throws Exception
    {
        jSession = connection.getHeaderField("Set-Cookie"); 
        System.out.println("jSession: " + jSession);
    }

    public void disconnect() throws Exception
    {
        if(connection!=null)
        {
            connection.disconnect();
            connection = null;
            responseBody = "";
        }
    }

    public void getCrumb() throws Exception
    {
        try
        {
            openConnection("GET", "/crumbIssuer/api/json");
            readResponse();
            setSessionCookie();

            int crumbIndex = responseBody.indexOf("crumb\":\"");
            if(crumbIndex!=-1)
            {
                int crumbIndexEnd = responseBody.indexOf("\",\"", crumbIndex);

                crumb = responseBody.substring(crumbIndex + "crumb\":\"".length(), crumbIndexEnd);
                System.out.println(crumb);
            }
        }
        finally
        {
            disconnect();
        }
    }

    public void runJob() throws Exception
    {
        try
        {
            openConnection("POST", "/job/test/build");

            connection.setDoOutput(true);
            connection.setRequestProperty("Cookie", jSession);
            connection.setRequestProperty("Jenkins-Crumb", crumb);

            readResponse();
            System.out.println("Post response: " + responseBody);
        }
        finally
        {
            disconnect();
        }
    }

    public static void main(String[] args)
    {
        JobRunner jobRunner = new JobRunner();

        try
        {
            jobRunner.getCrumb();

            jobRunner.runJob();
        }
        catch (Exception err)
        {
            err.printStackTrace();
        }
    }
}