Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to pac4j 6.x and migrate to EE 9 #455

Merged
merged 10 commits into from
Jan 10, 2025
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ jobs:
java-version: '17'
check-latest: true
cache: 'maven'
# https://github.com/jenkins-infra/github-reusable-workflows/issues/36
- name: Set up Maven
run: |
wget --no-verbose https://downloads.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
echo $CHECKSUM apache-maven-$MAVEN_VERSION-bin.tar.gz | sha512sum --check
tar xzf apache-maven-$MAVEN_VERSION-bin.tar.gz
rm apache-maven-$MAVEN_VERSION-bin.tar.gz
sudo mv apache-maven-$MAVEN_VERSION /opt/maven
sudo rm -f /usr/bin/mvn
sudo ln -s /opt/maven/bin/mvn /usr/bin/mvn
mvn --version
env:
MAVEN_VERSION: 3.9.9
# https://downloads.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz.sha512
CHECKSUM: a555254d6b53d267965a3404ecb14e53c3827c09c3b94b5678835887ab404556bfaf78dcfe03ba76fa2508649dca8531c74bca4d5846513522404d48e8c4ac8b
- name: Generate coverage with JaCoCo
run: mvn --batch-mode clean verify jacoco:prepare-agent test integration-test jacoco:report

Expand Down
1 change: 0 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ buildPlugin(useContainerAgent: true,
artifactCachingProxyEnabled: true,
configurations: [
[platform: 'linux', jdk: 21],
[platform: 'linux', jdk: 11],
[platform: 'windows', jdk: 17],
])
76 changes: 51 additions & 25 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.87</version>
<version>5.2</version>
<relativePath />
</parent>

Expand Down Expand Up @@ -45,22 +45,20 @@
<revision>4</revision>
<changelist>999999-SNAPSHOT</changelist>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
<!-- update the jenkins-bom version when updating -->
<jenkins.version>2.426.3</jenkins.version>
<jenkins.baseline>2.479</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
<spotless.check.skip>false</spotless.check.skip>
<spotbugs.effort>Max</spotbugs.effort>
<configuration-as-code.version>1836.vccda_4a_122a_a_e</configuration-as-code.version>
<hpi.compatibleSinceVersion>4.383</hpi.compatibleSinceVersion>
<!-- latest 5.x as 6 uses java 17 -->
<pac4jVersion>5.7.7</pac4jVersion>
<pac4jVersion>6.0.6</pac4jVersion>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.426.x</artifactId>
<version>3208.vb_21177d4b_cd9</version>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>3482.vc10d4f6da_28a_</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -93,6 +91,10 @@
<groupId>io.jenkins.plugins</groupId>
<artifactId>asm-api</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>commons-text-api</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
Expand All @@ -104,18 +106,18 @@

<dependency>
<groupId>org.pac4j</groupId>
<!-- replace with pac4j-jakartaee when we use a Jenkins version with jakartaee -->
<artifactId>pac4j-javaee</artifactId>
<artifactId>pac4j-jakartaee</artifactId>
<version>${pac4jVersion}</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<!-- consume from jackson2-api plugin -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<!-- consume from asm-api plugin -->
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<!-- consume from commons-text-api plugin -->
<groupId>commons-text</groupId>
<artifactId>commons-text</artifactId>
</exclusion>
<exclusion>
<!-- consume from Jenkins core -->
Expand All @@ -128,35 +130,55 @@
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oidc</artifactId>
<version>${pac4jVersion}</version>
<!-- java 11 compatability-->
<exclusions>
<exclusion>
<!-- consume from jackson2-api plugin -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<!-- consume from Jenkins core -->
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<!-- consume from commons-text-api plugin -->
<groupId>commons-text</groupId>
<artifactId>commons-text</artifactId>
</exclusion>
<exclusion>
<!-- consume from Jenkins core -->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<!-- consume from Jenkins core -->
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.36.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<!-- consume from Jenkins core -->
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<!-- consume from apache-httpcomponents-client-4-api plugin -->
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
<exclusion>
<!-- consume from apache-httpcomponents-client-4-api plugin -->
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
Expand All @@ -165,9 +187,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
<groupId>io.jenkins.plugins</groupId>
<artifactId>gson-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>apache-httpcomponents-client-4-api</artifactId>
<scope>test</scope>
basil marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@
import java.util.logging.Logger;
import org.pac4j.core.exception.TechnicalException;
import org.pac4j.oidc.config.OidcConfiguration;
import org.pac4j.oidc.metadata.OidcOpMetadataResolver;
import org.pac4j.oidc.metadata.StaticOidcOpMetadataResolver;
import org.pac4j.oidc.profile.creator.TokenValidator;

public class AnythingGoesTokenValidator extends TokenValidator {

public static final Logger LOGGER = Logger.getLogger(AnythingGoesTokenValidator.class.getName());

public AnythingGoesTokenValidator() {
super(createFakeOidcConfiguration());
this(createFakeOidcProviderMetadata());
}

public AnythingGoesTokenValidator(OIDCProviderMetadata metadata) {
super(createFakeOidcConfiguration(metadata), metadata);
}

@Override
Expand All @@ -50,18 +56,23 @@ public IDTokenClaimsSet validate(final JWT idToken, final Nonce expectedNonce) {
* which if we are not validating we may not actually have (e.g. jwks_url).
* So we need a configuration with this set just so the validator can say "this is valid".
*/
private static OidcConfiguration createFakeOidcConfiguration() {
private static OidcConfiguration createFakeOidcConfiguration(OIDCProviderMetadata metadata) {
OidcConfiguration config = new OidcConfiguration();
config.setClientId("ignored");
config.setSecret("ignored");
OidcOpMetadataResolver opMetadataResolver = new StaticOidcOpMetadataResolver(config, metadata);
config.setOpMetadataResolver(opMetadataResolver);
config.setPreferredJwsAlgorithm(JWSAlgorithm.HS256);
config.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
return config;
}

private static OIDCProviderMetadata createFakeOidcProviderMetadata() {
try {
OidcConfiguration config = new OidcConfiguration();
config.setClientId("ignored");
config.setSecret("ignored");
OIDCProviderMetadata providerMetadata = new OIDCProviderMetadata(
new Issuer("http://ignored"), List.of(SubjectType.PUBLIC), new URI("http://ignored.and.invalid./"));
providerMetadata.setIDTokenJWSAlgs(List.of(JWSAlgorithm.HS256));
config.setProviderMetadata(providerMetadata);
config.setPreferredJwsAlgorithm(JWSAlgorithm.HS256);
config.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
return config;
return providerMetadata;
} catch (URISyntaxException e) {
// should never happen the urls we are using are valid
throw new IllegalStateException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CustomOidcConfiguration extends OidcConfiguration {

@Override
public void configureHttpRequest(HTTPRequest request) {
super.configureHttpRequest(request);
Proxy proxy = null;
Jenkins jenkins = Jenkins.getInstanceOrNull();
if (jenkins != null) { // unit tests
Expand All @@ -47,6 +48,5 @@ public void configureHttpRequest(HTTPRequest request) {
throw new IllegalStateException("could not configure the SSLFactory, this should not be possible", e);
}
}
super.configureHttpRequest(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import hudson.Extension;
import hudson.security.csrf.CrumbExclusion;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Excluding the escapeHatch login from CSRF protection as the crumb is calculated based on the authentication
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.jenkinsci.plugins.oic;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import jakarta.servlet.ServletException;
import java.io.IOException;
import javax.servlet.ServletException;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.StaplerRequest2;
import org.kohsuke.stapler.StaplerResponse2;

/**
* Exception to be thrown when the received ID Token did not pass the expected check.
Expand All @@ -26,7 +26,7 @@ public String getIdpLogoutUrl() {
}

@Override
public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node)
public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node)
throws IOException, ServletException {
req.getView(this, "error").forward(req, rsp);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/jenkinsci/plugins/oic/OicCredentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.io.Serializable;
import net.sf.json.JSONObject;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerRequest2;

public class OicCredentials extends UserProperty implements Serializable {
static final String PROPERTY_NAME = "oicCredentials";
Expand All @@ -23,7 +23,7 @@ public class OicCredentials extends UserProperty implements Serializable {
private final Long expiresAtMillis;

@Override
public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws Descriptor.FormException {
public UserProperty reconfigure(StaplerRequest2 req, JSONObject form) throws Descriptor.FormException {
req.bindJSON(this, form);
return this;
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/jenkinsci/plugins/oic/OicCrumbExclusion.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import hudson.Extension;
import hudson.security.SecurityRealm;
import hudson.security.csrf.CrumbExclusion;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jenkins.model.Jenkins;

/**
* Crumb exclusion to allow POSTing to {@link OicSecurityRealm#doFinishLogin(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)}
* Crumb exclusion to allow POSTing to {@link OicSecurityRealm#doFinishLogin(org.kohsuke.stapler.StaplerRequest2, org.kohsuke.stapler.StaplerResponse2)}
*/
@Extension
public class OicCrumbExclusion extends CrumbExclusion {
Expand Down
Loading