簡體   English   中英

JENKINS REST API 拋出 403 禁止

[英]JENKINS REST API throws 403 forbidden

問題陳述

我有 Jenkins Sever V:2.190.2 在雲上運行。 在 Jenkins Config Security 上選擇了“登錄用戶可以做任何事情”權限。 因此,這意味着具有有效用戶名和密碼的用戶可以登錄到 jenkin 服務器並執行授權的工作。 基本上我需要通過傳遞作業名稱和 jobXml 在 Jenkins 服務器上創建作業。

嘗試以下選項

到目前為止,我已經使用了 Github 上的“jenkinsci/java-client-api”api。 對於 Jenkins 相關操作,這個 api 非常好 api,我按照 READ.md 中給出的說明進行操作。 我創建了 Jenkins 服務器實例並嘗試調用 getJenkinVersion() 和 getJobs() 方法,兩者都運行良好並按預期返回結果。 但是,當我要調用 createJob(jobName, jobXml) 時,此調用會從服務器返回 403 禁止錯誤。

通過深入研究這個問題,我發現了以下內容:- 1. 當我將 Jenkins 安全配置更改為“任何用戶可以做任何事情”時,這個 createJob() 方法就可以工作並且我能夠創建工作。 但是,由於安全限制,不建議使用此選項。 2. 當我將 Jenkins 安全配置保持為“登錄用戶可以做任何事情”時,createJob() 方法不起作用並返回 403 禁止錯誤。 在這里我還注意到,雖然我提供了正確的用戶名和密碼/令牌,用於登錄,但從 UI 登錄到 Jenkins 服務器以創建用戶文檔中定義的 Jenkins 服務器實例,但當它到達該方法時,它是以“匿名用戶”身份登錄到詹金。 我認為這是返回 403 錯誤的根本原因。

下面的代碼片段

**Sample 1**:
        HttpClientBuilder builder = HttpClientBuilder.create();
        JenkinsHttpClient client = new JenkinsHttpClient(uri, builder, "XXX", "XXX");
        JenkinsServer jenkins = new JenkinsServer(client);
        String sourceXML = readFile("src/main/resources/config.xml");
        System.out.println(String.format("Installed Jenkins Version >> %s", jenkins.getVersion().getLiteralVersion()));//works and gives correct result
        jenkins.createJob("test-nov1", sourceXML);

**Sample 2**:
        HttpClientBuilder builder = HttpClientBuilder.create();
        JenkinsHttpClient client = new JenkinsHttpClient(uri, addAuthentication(builder, uri, userName, passwordOrToken));
        JenkinsServer jenkins = new JenkinsServer(client);
        String sourceXML = readFile("src/main/resources/config.xml");
        System.out.println(String.format("Installed Jenkins Version >> %s", jenkins.getVersion().getLiteralVersion()));
        jenkins.createJob(null,"test-nov1", sourceXML,true);

**Sample Exception**:
    Exception in thread "main" org.apache.http.client.HttpResponseException: status code: 403, reason phrase: Forbidden
    at com.offbytwo.jenkins.client.validator.HttpResponseValidator.validateResponse(HttpResponseValidator.java:11)
    at com.offbytwo.jenkins.client.JenkinsHttpClient.post_xml(JenkinsHttpClient.java:375)
    at com.offbytwo.jenkins.JenkinsServer.createJob(JenkinsServer.java:389)
    at com.offbytwo.jenkins.JenkinsServer.createJob(JenkinsServer.java:359)
    at com.xx.OffByTwoJenkins.main(OffByTwoJenkins.java:31)

選項2 :我還嘗試了其他選項,直接使用HttpUrl連接直接調用Jenkins REST API。

**Sample Code** :
public int createJob(final String username, final String password, final String jenkinsUrl, final String jobName) {
        // http://JENKINSURL//createItem?name=JOBNAME
        String jobUrl = jenkinsUrl + "/createItem?name=" + jobName;

        int responseCode = 00;
        try {
            String basicAuth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
            //String encoding = Base64.getEncoder().encodeToString((username+":"+password).getBytes("utf-8"));
            System.out.println(String.format("User Auth >> %s", basicAuth));
            String sourceXML = readFile("src/main/resources/config.xml");
            URL url = new URL(jobUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            //connection.setReadTimeout(10000);
            //connection.setConnectTimeout(15000);
            connection.setRequestProperty("Authorization", "Basic " + basicAuth);
            connection.setRequestProperty("Content-Type", "application/xml");
            connection.setRequestProperty("Content-Language", "en-US");
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setInstanceFollowRedirects(false);
            OutputStream os = connection.getOutputStream();
            os.write(sourceXML.getBytes());
            os.flush();
            responseCode = connection.getResponseCode();
            BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
            String output;
            System.out.println("Output from Server .... \n");
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return responseCode;

    }

This also returns with same error 403 forbidden.

**Exception** :
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: <<JenkinsURL>>
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at com.xx.JenkinsJobExecutor.createJob(JenkinsJobExecutor.java:109)

我真的不明白我需要在哪里調整才能獲得工作。 謝謝

即使在啟用 CSRF 之后,以下解決方案也對我有用。

public class JenkinsJobCreate {
public static void main(String[] args) {

    System.out.println("JenkinsJobsTrigger has started ###############################");

    String ipAddress = "http://localhost:8080/";
    String jobName = "Hello-world";

    String username = "admin";
    String password = "admin";

    System.out.println("ipAddress: " + ipAddress);
    System.out.println("jobName: " + jobName);

    System.out.println("username: " + username);
    System.out.println("password: " + password);


    try (JenkinsServer jenkinsServer = new JenkinsServer(new URI(ipAddress), username, password)) {

        // our XML file for this example
        File xmlFile = new File("src/main/resources/config.xml");

        // Let's get XML file as String using BufferedReader
        // FileReader uses platform's default character encoding
        // if you need to specify a different encoding, use InputStreamReader
        Reader fileReader = new FileReader(xmlFile);
        BufferedReader bufReader = new BufferedReader(fileReader);

        StringBuilder sb = new StringBuilder();
        String line = bufReader.readLine();
        while( line != null){
            sb.append(line).append("\n");
            line = bufReader.readLine();
        }
        String jobXml = sb.toString();
        System.out.println("XML to String using BufferedReader : ");
        System.out.println(jobXml);

        bufReader.close();

        jenkinsServer.createJob(jobName, jobXml, true);

    } catch (Exception e) {
        System.out.println("Exception Occured!!!");
        e.printStackTrace();
    }

    System.out.println("JenkinsJobsTrigger has Finished ###############################");

}

}

config.xml

<?xml version='1.1' encoding='UTF-8'?>
<project>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <scm class="hudson.scm.NullSCM"/>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>echo &quot;Jenkins Testing Hello World!&quot;</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers/>
  <buildWrappers/>
</project>

我的訣竅就是使用標准語法在 URL 中包含用戶名和密碼。

這是我使用的 CURL:

curl -I http://user:gNouIkl2ca1t@54.226.181.123/job/RemoteTriggerExample/build?token=abc-123

因此,如果沒有用戶名和密碼,它會給出 403。使用 URL 中的用戶名和密碼,它可以正常工作。

小費? 可能要使用 https 而不是 http。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM