0

I'm trying to connect to Jenkins using Java based on https://wiki.jenkins.io/display/JENKINS/Authenticating+scripted+clients

I am always getting 401 Unauthorized error. User name and password are correct, I can login to Jenkins using them through browser. I also tried token in place of password but it also fails with same error.

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());
    }

}

I want to understand why my request is unauthorized when credentials are correct and how can I fix it.

Error Message

    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>
anurag
  • 1
  • 1
  • 1

2 Answers2

1

Following code worked perfectly for me:

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();
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
0

I faced this issue because of missing java cacerts file for Jenkins server. It was fixed after following steps documented here https://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed/.

anurag
  • 1
  • 1
  • 1
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Saeid Amini Dec 16 '20 at 06:55