Jenkins客户端实现未对Jenkins服务器进行身份验证

后端开发 2026-07-09

请查看下面的代码,看看是否正确。按当前实现会返回403错误。


这是一个用于运行2 个Jenkins作业的Java程序的一部分。

“Map keys” 是来自表中的列名,我在其中存储URI、用户名、API令牌,以及要触发的作业路径的值。“config” 输入是一个JSONArray,用来保存这些值。“logger” 输入是一个log4j实现。字符串“env”输入是Jenkins作业用来指定要使用的服务器环境的关键字(DEVELOPMENT、TEST等)。

如果你想复现这个问题,可以添加重载来强制设置所有配置值(使用你自己的URI、用户名、API令牌,以及测试作业的路径)。

我在与我的登录ID关联的Jenkins服务器上创建了一个API令牌。运行代码时返回403,当我查看我的Jenkins个人资料时,它显示为“从未使用过”(我不知道这是否表示“从未尝试使用”还是“从未用它成功登录过”)。不确定含义,我尝试了API令牌的名称和API令牌的值。

API 令牌配置的截图

我们的Jenkins服务器使用自签名证书,因此我不得不添加代码来忽略证书违规。这是我正在使用的客户端库:

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;

代码

    public boolean deployCertificate(Logger logger, JSONArray config, String env) {
        boolean procRun = false;
        // Define map keys
        final String MYJOB = "TOP_CERTIFICATE_DEPLOY";
        final String MYURL = "TOP_JENKINS_BASE_URL";
        final String MYLID = "TOP_JENKINS_ID";
        final String MYLPW = "TOP_JENKINS_AUTH";
        // Create JSON Object from JSONArray "config"
        JSONObject jsonObject = config.getJSONObject(0);
        Map<String,String> jenkParams = new HashMap<String,String>();
        jenkParams.put("ENV", env);

        // Set up CloseableHttpClient because the Jenkins server has a self-signed certificate
        try {
            CredentialsProvider provider = new BasicCredentialsProvider();
            // The password is a Jenkins API token
            provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(jsonObject.getString(MYLID), jsonObject.getString(MYLPW)));
            URI jenkinsUri = new URI(jsonObject.getString(MYURL));
            SSLContext sslContext = new SSLContextBuilder()
                    .loadTrustMaterial(null, (chain, authType) -> true)
                    .build();
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                    sslContext, 
                    new AllowAllHostnameVerifier()
                    );
            CloseableHttpClient httpClient = HttpClientBuilder
                    .create()
                    .setSSLSocketFactory(socketFactory)
                    .setDefaultCredentialsProvider(provider)
                    .build(); 
            JenkinsHttpClient client = new JenkinsHttpClient(
                    jenkinsUri,
                    httpClient
                    );
            JenkinsServer jenkinsServer = new JenkinsServer(client);
            jenkinsServer.getJob(jsonObject.getString(MYJOB)).build(jenkParams);
            jenkinsServer.close();
            procRun = true;
        } catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException | URISyntaxException e) {
            logger.error("Jenkins job {} failed: " + e);
            return procRun;
        }
        return procRun;
    }

解决方案

问题很可能在于所使用的API令牌是令牌名称/ID(c03999 在截图中)而非实际生成的令牌值。在Jenkins中,显示的短字符串只是令牌标识符,真正的秘密令牌只在创建令牌时显示一次。"Never used" 状态表示Jenkins还没有使用该令牌收到过成功的认证请求。

在认证时,代码应使用:

  • 用户名 = Jenkins登录ID
  • 密码 = 实际的API令牌值

而不是令牌名称。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章