java - 如何在使用 java API 并提供正确的凭据时修复 Jenkins 401 Unauthorized
问题描述
我正在尝试使用基于https://wiki.jenkins.io/display/JENKINS/Authenticating+scripted+clients的 Java 连接到 Jenkins
我总是收到 401 Unauthorized 错误。用户名和密码正确,我可以通过浏览器使用它们登录 Jenkins。我也尝试使用令牌代替密码,但它也因同样的错误而失败。
import java.io.IOException;
import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class JenkinsScraper {
public static void main(String[] args) throws ClientProtocolException, IOException {
System.out.println(scrape(
"JenkinUrl",
"user",
"token" // "password"
));
}
public static String scrape(String urlString, String username, String password) throws ClientProtocolException, IOException {
URI uri = URI.create(urlString);
HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(host, basicAuth);
CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpGet httpGet = new HttpGet(uri);
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
HttpResponse response = httpClient.execute(host, httpGet, localContext);
System.out.println(response);
return EntityUtils.toString(response.getEntity());
}
}
我想了解为什么当凭据正确时我的请求是未经授权的,以及如何解决它。
错误信息
HttpResponseProxy{HTTP/1.1 401 Unauthorized [Date: Thu, 15 Aug 2019 15:33:31 GMT, Server: Apache/2.4.39 (Win64) mod_authn_ntlm/1.0.8 OpenSSL/1.0.2r, WWW-Authenticate: NTLM, WWW-Authenticate: Basic realm="Private location", Content-Length: 381, Keep-Alive: timeout=5, max=100, Connection: Keep-Alive, Content-Type: text/html; charset=iso-8859-1] ResponseEntityProxy{[Content-Type: text/html; charset=iso-8859-1,Content-Length: 381,Chunked: false]}}
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested. Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
</body></html>
解决方案
以下代码对我来说非常有效:
try
{
URL url = new URL("http://localhost:8080/job/TestPrj/build"); // Jenkins URL localhost:8080, job named 'test'
String user = "username"; // username
String pass = "apitokengeneratedfromjenkins"; // password or API token
String authStr = user + ":" + pass;
String encoding = Base64.getEncoder().encodeToString(authStr.getBytes("utf-8"));
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Authorization", "Basic " + encoding);
InputStream content = connection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = in.readLine()) != null)
{
System.out.println(line);
}
}
catch (Exception e)
{
e.printStackTrace();
}
推荐阅读
- pandas - 合并不同 pandas 数据帧的 value_counts
- sharepoint - Sharepoint 列表:如果存在则更新项目或创建没有流程或任何代码的新项目
- javascript - 在 vue 应用程序中使用 array.includes
- python - 如何将 tkinter 应用程序转换为图像?
- python - 在 Python 的 for 循环中迭代变量对以减少代码冗余
- oracle - 如何将当前小时和分钟添加到插入的日期
- flutter - 限制 Map 中 MapEntries 的数量:Dart
- r - 错误:无法在未命名的向量中选择
- azure-cosmosdb - 在 cosmosDB/MongoDB API 中,使用排序规则选项 numericOrdering 按包含数字的字符串字段进行排序不起作用
- python - TypeError:“PosixPath”类型的参数不可迭代,旧解决方案不起作用