Java 詹金斯REST API抛出403禁止
问题陈述:Java 詹金斯REST API抛出403禁止,java,rest,jenkins,http-post,jenkins-cli,Java,Rest,Jenkins,Http Post,Jenkins Cli,问题陈述: **Sample 1**: HttpClientBuilder builder = HttpClientBuilder.create(); JenkinsHttpClient client = new JenkinsHttpClient(uri, builder, "XXX", "XXX"); JenkinsServer jenkins = new JenkinsServer(client); String source
**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)
我让詹金斯服务器V:2.190.2在云上运行。在Jenkins Config Security上选择权限“登录用户可以做任何事情”。
因此,这意味着拥有有效用户名和密码的用户可以登录到jenkin服务器并执行授权作业。基本上我需要创造就业机会
在Jenkin服务器上,通过传递作业名称和作业XML
尝试以下选项:
**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)
到目前为止,我已经使用了Github上提供的“jenkinsci/java客户端api”api。这个api对于Jenkins相关的操作来说是非常好的api,我遵循了这个api
READ.md上给出的说明。我创建了Jenkins服务器实例,并尝试调用getJenkinVersion()和getJobs()方法,这两种方法都很好
并按预期返回结果。
但是,当我要调用createJob(jobName,jobXml)时,这个调用从服务器返回403禁止的错误
通过深入挖掘,我发现以下几点:-
1.当我将Jenkin安全配置更改为“任何用户都可以做任何事情”时,这个createJob()方法就可以工作了,我就可以创建作业了。
但是,由于安全限制,不建议使用此选项。
2.当我将Jenkin安全配置保持为“登录用户可以做任何事情”时,createJob()方法不起作用,并返回403禁止的错误。
在这里,我还注意到,尽管我提供了正确的用户名和密码/令牌(用于登录),但还是从UI登录到Jenkins服务器以创建
用户文档中定义的Jenkin服务器实例,当它点击该方法时,它作为“匿名用户”登录到Jenkin。我想这是
返回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连接直接调用JenkinRESTAPI
**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)
**示例代码**:
public int createJob(最终字符串用户名、最终字符串密码、最终字符串URL、最终字符串jobName){
// http://JENKINSURL//createItem?name=JOBNAME
字符串jobUrl=jenkinsUrl+“/createItem?name=“+jobName;
int-responseCode=00;
试一试{
字符串basicAuth=Base64.getEncoder().encodeToString((用户名+“:”+密码).getBytes(StandardCharsets.UTF_8));
//字符串编码=Base64.getEncoder().encodeToString((用户名+“:”+密码).getBytes(“utf-8”);
System.out.println(String.format(“用户身份验证>>%s”,basicAuth));
字符串sourceXML=readFile(“src/main/resources/config.xml”);
URL URL=新URL(作业URL);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//connection.setReadTimeout(10000);
//连接。设置连接超时(15000);
connection.setRequestProperty(“授权”、“基本”+basicAuth);
setRequestProperty(“内容类型”、“应用程序/xml”);
connection.setRequestProperty(“内容语言”、“en-US”);
connection.setRequestMethod(“POST”);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(真);
connection.setInstanceFollowDirections(false);
OutputStream os=connection.getOutputStream();
write(sourceXML.getBytes());
os.flush();
responseCode=connection.getResponseCode();
BufferedReader br=新的BufferedReader(新的InputStreamReader((connection.getInputStream()));
字符串输出;
System.out.println(“从服务器输出…”\n);
而((output=br.readLine())!=null){
系统输出打印项次(输出);
}
连接断开();
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
返回响应代码;
}
这也返回相同的错误403禁止。
**例外**:
原因:java.io.IOException:服务器返回了URL的HTTP响应代码:403:
位于sun.net.www.protocol.http.HttpURLConnection.getInputStream0(未知源)
位于sun.net.www.protocol.http.HttpURLConnection.getInputStream(未知源)
位于java.net.HttpURLConnection.getResponseCode(未知源)
在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 "Jenkins Testing Hello World!"</command>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
假的
真的
假的
假的
假的
假的
echo“Jenkins正在测试Hello World!”
我的窍门就是用标准语法在URL中包含用户名和密码
这是我使用的卷曲:
curl -I http://user:gNouIkl2ca1t@54.226.181.123/job/RemoteTriggerExample/build?token=abc-123
因此,如果没有用户名和密码,它将显示403。使用URL中的用户名和密码,它可以正常工作
小费?您可能希望使用https而不是http。非常感谢您的回答。你有一些示例代码吗。我不太喜欢cookies等。我想在这里指出的另一点是,我们没有启用CSRF。因此,我认为,没有必要对这个请求置之不理。请您发布示例代码(如果有)。ThanksI尝试只使用CURL而不是像您所做的那样使用Java来使用API。但是,如果我能找到使用相同的解决方案,我将尝试用Java发布示例代码。您是否在Jenkins配置中禁用了CSRF?如果是,请尽量避免这样做,建议保持启用状态。是的,目前已禁用。但我会尽力让它启用。但到目前为止,最大的问题是使用Java调用创建作业。这就是为什么我也发布了代码示例(根据您的建议,这是使用HttpUrlConnection的上述代码示例中的选项2)。我尝试点击restapiget方法从我的jenkins服务器获取crump,但再次尝试