diff --git a/.gitignore b/.gitignore
index d93daae7..02fb8b07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,6 @@ target/
/.apt_generated/
.*.swp
+
+work-cognito/
+work-keycloak/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 175e662d..e10156a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.jenkins-ci.plugins
plugin
- 4.87
+ 5.3
@@ -45,14 +45,14 @@
4
999999-SNAPSHOT
jenkinsci/${project.artifactId}-plugin
-
- 2.426.3
false
Max
1836.vccda_4a_122a_a_e
4.383
- 5.7.7
+ 6.1.0
+ 6.1.14
+ 2.18.1
@@ -64,16 +64,6 @@
pom
import
-
-
- com.nimbusds
- nimbus-jose-jwt
- 9.47
-
-
com.github.stephenc.jcip
@@ -104,10 +94,17 @@
org.pac4j
-
- pac4j-javaee
+ pac4j-jakartaee
${pac4jVersion}
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
com.google.guava
guava
@@ -139,8 +136,18 @@
com.google.guava
guava
+
+ org.springframework
+ spring-core
+
+
+ org.springframework
+ spring-jcl
+
+
+
com.google.code.gson
gson
@@ -301,5 +308,4 @@
-
diff --git a/src/main/java/org/jenkinsci/plugins/oic/AnythingGoesTokenValidator.java b/src/main/java/org/jenkinsci/plugins/oic/AnythingGoesTokenValidator.java
index 2bdb56ca..6a165023 100644
--- a/src/main/java/org/jenkinsci/plugins/oic/AnythingGoesTokenValidator.java
+++ b/src/main/java/org/jenkinsci/plugins/oic/AnythingGoesTokenValidator.java
@@ -24,7 +24,7 @@ public class AnythingGoesTokenValidator extends TokenValidator {
public static final Logger LOGGER = Logger.getLogger(AnythingGoesTokenValidator.class.getName());
public AnythingGoesTokenValidator() {
- super(createFakeOidcConfiguration());
+ super(createFakeOidcConfiguration(), createFakeProviderMetadata());
}
@Override
@@ -51,17 +51,25 @@ public IDTokenClaimsSet validate(final JWT idToken, final Nonce expectedNonce) {
* So we need a configuration with this set just so the validator can say "this is valid".
*/
private static OidcConfiguration createFakeOidcConfiguration() {
+ OidcConfiguration config = new OidcConfiguration();
+ config.setClientId("ignored");
+ config.setSecret("ignored");
+ config.setPreferredJwsAlgorithm(JWSAlgorithm.HS256);
+ config.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+ return config;
+ }
+
+ /**
+ * Annoyingly the super class needs an OIDCProviderMetadata with some values set,
+ * which if we are not validating we may not actually have (e.g. jwks_url).
+ * So we need a metadata provider with this set just so the validator can say "this is valid".
+ */
+ private static OIDCProviderMetadata createFakeProviderMetadata() {
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);
diff --git a/src/main/java/org/jenkinsci/plugins/oic/CustomOidcConfiguration.java b/src/main/java/org/jenkinsci/plugins/oic/CustomOidcConfiguration.java
index 5f1878b4..2700af24 100644
--- a/src/main/java/org/jenkinsci/plugins/oic/CustomOidcConfiguration.java
+++ b/src/main/java/org/jenkinsci/plugins/oic/CustomOidcConfiguration.java
@@ -39,6 +39,9 @@ public void configureHttpRequest(HTTPRequest request) {
}
}
request.setProxy(proxy);
+ // super class will configure the hostname verifier and the SSL socket factory and the default values in case
+ // the config object doesn't have those values must be overrriden in case the disableTLS is true
+ super.configureHttpRequest(request);
if (disableTLS) {
request.setHostnameVerifier(IgnoringHostNameVerifier.INSTANCE);
try {
@@ -47,6 +50,5 @@ public void configureHttpRequest(HTTPRequest request) {
throw new IllegalStateException("could not configure the SSLFactory, this should not be possible", e);
}
}
- super.configureHttpRequest(request);
}
}
diff --git a/src/main/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusion.java b/src/main/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusion.java
index c888ed12..65ba3f8e 100644
--- a/src/main/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusion.java
+++ b/src/main/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusion.java
@@ -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
diff --git a/src/main/java/org/jenkinsci/plugins/oic/OicCrumbExclusion.java b/src/main/java/org/jenkinsci/plugins/oic/OicCrumbExclusion.java
index d7e0141e..72f11e9f 100644
--- a/src/main/java/org/jenkinsci/plugins/oic/OicCrumbExclusion.java
+++ b/src/main/java/org/jenkinsci/plugins/oic/OicCrumbExclusion.java
@@ -3,11 +3,11 @@
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;
/**
diff --git a/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java b/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java
index ca151330..5dfc6301 100644
--- a/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java
+++ b/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java
@@ -46,7 +46,7 @@
import hudson.model.Descriptor.FormException;
import hudson.model.Failure;
import hudson.model.User;
-import hudson.security.ChainedServletFilter;
+import hudson.security.ChainedServletFilter2;
import hudson.security.SecurityRealm;
import hudson.tasks.Mailer;
import hudson.util.FormValidation;
@@ -55,6 +55,15 @@
import io.burt.jmespath.JmesPath;
import io.burt.jmespath.RuntimeConfiguration;
import io.burt.jmespath.jcf.JcfRuntime;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
@@ -79,15 +88,6 @@
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
import jenkins.model.Jenkins;
import jenkins.security.ApiTokenProperty;
import jenkins.security.FIPS140;
@@ -102,9 +102,11 @@
import org.kohsuke.stapler.Header;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.Stapler;
-import org.kohsuke.stapler.StaplerRequest;
-import org.kohsuke.stapler.StaplerResponse;
+import org.kohsuke.stapler.StaplerRequest2;
+import org.kohsuke.stapler.StaplerResponse2;
import org.kohsuke.stapler.interceptor.RequirePOST;
+import org.pac4j.core.context.CallContext;
+import org.pac4j.core.context.FrameworkParameters;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.credentials.Credentials;
@@ -114,11 +116,13 @@
import org.pac4j.core.http.callback.NoParameterCallbackUrlResolver;
import org.pac4j.core.profile.creator.ProfileCreator;
import org.pac4j.jee.context.JEEContextFactory;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import org.pac4j.jee.context.session.JEESessionStoreFactory;
import org.pac4j.jee.http.adapter.JEEHttpActionAdapter;
import org.pac4j.oidc.client.OidcClient;
import org.pac4j.oidc.config.OidcConfiguration;
import org.pac4j.oidc.credentials.authenticator.OidcAuthenticator;
+import org.pac4j.oidc.metadata.OidcOpMetadataResolver;
import org.pac4j.oidc.profile.OidcProfile;
import org.pac4j.oidc.redirect.OidcRedirectionActionBuilder;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
@@ -172,23 +176,23 @@ ClientAuthenticationMethod toClientAuthenticationMethod() {
@Deprecated
private transient String wellKnownOpenIDConfigurationUrl;
- /** @deprecated see {@link OicServerConfiguration#getTokenServerUrl()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getTokenServerUrl()} */
@Deprecated
private transient String tokenServerUrl;
- /** @deprecated see {@link OicServerConfiguration#getJwksServerUrl()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getJwksServerUrl()} */
@Deprecated
private transient String jwksServerUrl;
- /** @deprecated see {@link OicServerConfiguration#getTokenAuthMethod()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getTokenAuthMethod()} */
@Deprecated
private transient TokenAuthMethod tokenAuthMethod;
- /** @deprecated see {@link OicServerConfiguration#getAuthorizationServerUrl()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getAuthorizationServerUrl()} */
@Deprecated
private transient String authorizationServerUrl;
- /** @deprecated see {@link OicServerConfiguration#getUserInfoServerUrl()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getUserInfoServerUrl()} */
@Deprecated
private transient String userInfoServerUrl;
@@ -206,14 +210,14 @@ ClientAuthenticationMethod toClientAuthenticationMethod() {
private transient String simpleGroupsFieldName = null;
private transient String nestedGroupFieldName = null;
- /** @deprecated see {@link OicServerConfiguration#getScopes()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getScopes()} */
@Deprecated
private transient String scopes = null;
private final boolean disableSslVerification;
private boolean logoutFromOpenidProvider = true;
- /** @deprecated see {@link OicServerConfiguration#getEndSessionUrl()} */
+ /** @deprecated see {@link OicServerManualConfiguration#getEndSessionUrl()} */
@Deprecated
private transient String endSessionEndpoint = null;
@@ -517,11 +521,15 @@ private OidcConfiguration buildOidcConfiguration() {
OIDCProviderMetadata oidcProviderMetadata = serverConfiguration.toProviderMetadata();
filterNonFIPS140CompliantAlgorithms(oidcProviderMetadata);
+ OidcOpMetadataResolver metadataResolver;
if (this.isDisableTokenVerification()) {
conf.setAllowUnsignedIdTokens(true);
- conf.setTokenValidator(new AnythingGoesTokenValidator());
+ metadataResolver = new OicdPluginOpMetadataResolver(conf, oidcProviderMetadata, true);
+ } else {
+ metadataResolver = new OicdPluginOpMetadataResolver(conf, oidcProviderMetadata, false);
}
- conf.setProviderMetadata(oidcProviderMetadata);
+ conf.setOpMetadataResolver(metadataResolver);
+
if (oidcProviderMetadata.getScopes() != null) {
// auto configuration does not need to supply scopes
conf.setScope(oidcProviderMetadata.getScopes().toString());
@@ -533,6 +541,8 @@ private OidcConfiguration buildOidcConfiguration() {
conf.setResourceRetriever(getResourceRetriever());
if (this.isPkceEnabled()) {
conf.setPkceMethod(CodeChallengeMethod.S256);
+ } else {
+ conf.setDisablePkce(true);
}
return conf;
}
@@ -853,7 +863,7 @@ public String getAuthenticationGatewayUrl() {
@Override
public Filter createFilter(FilterConfig filterConfig) {
- return new ChainedServletFilter(super.createFilter(filterConfig), new Filter() {
+ return new ChainedServletFilter2(super.createFilter(filterConfig), new Filter() {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
@@ -933,7 +943,7 @@ protected String getValidRedirectUrl(String url) {
}
/**
- * Handles the the securityRealm/commenceLogin resource and sends the user off to the IdP
+ * Handles the securityRealm/commenceLogin resource and sends the user off to the IdP
* @param from the relative URL to the page that the user has just come from
* @param referer the HTTP referer header (where to redirect the user back to after login has finished)
* @throws URISyntaxException if the provided data is invalid
@@ -947,12 +957,13 @@ public void doCommenceLogin(@QueryParameter String from, @Header("Referer") fina
final String redirectOnFinish = getValidRedirectUrl(from != null ? from : referer);
OidcRedirectionActionBuilder builder = new OidcRedirectionActionBuilder(client);
- WebContext webContext =
- JEEContextFactory.INSTANCE.newContext(Stapler.getCurrentRequest(), Stapler.getCurrentResponse());
- SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore();
+ FrameworkParameters frameworkParameters =
+ new JEEFrameworkParameters(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2());
+ WebContext webContext = JEEContextFactory.INSTANCE.newContext(frameworkParameters);
+ SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore(frameworkParameters);
+ CallContext callContext = new CallContext(webContext, sessionStore);
RedirectionAction redirectionAction =
- builder.getRedirectionAction(webContext, sessionStore).orElseThrow();
-
+ builder.getRedirectionAction(callContext).orElseThrow();
// store the redirect url for after the login.
sessionStore.set(webContext, SESSION_POST_LOGIN_REDIRECT_URL_KEY, redirectOnFinish);
JEEHttpActionAdapter.INSTANCE.adapt(redirectionAction, webContext);
@@ -1149,7 +1160,7 @@ private List ensureString(Object field) {
}
@Restricted(DoNotUse.class) // stapler only
- public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
+ public void doLogout(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
User user = User.get2(authentication);
@@ -1172,7 +1183,7 @@ public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException
}
@Override
- public String getPostLogOutUrl2(StaplerRequest req, Authentication auth) {
+ public String getPostLogOutUrl2(StaplerRequest2 req, Authentication auth) {
Object idToken = req.getAttribute(ID_TOKEN_REQUEST_ATTRIBUTE);
Object state = getStateAttribute(req.getSession());
var openidLogoutEndpoint = maybeOpenIdLogoutEndpoint(
@@ -1187,12 +1198,15 @@ public String getPostLogOutUrl2(StaplerRequest req, Authentication auth) {
Object getStateAttribute(HttpSession session) {
// return null;
OidcClient client = buildOidcClient();
- WebContext webContext =
- JEEContextFactory.INSTANCE.newContext(Stapler.getCurrentRequest(), Stapler.getCurrentResponse());
- SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore();
+ FrameworkParameters frameworkParameters =
+ new JEEFrameworkParameters(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2());
+ WebContext webContext = JEEContextFactory.INSTANCE.newContext(frameworkParameters);
+ SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore(frameworkParameters);
+ CallContext callContext = new CallContext(webContext, sessionStore);
+
return client.getConfiguration()
.getValueRetriever()
- .retrieve(client.getStateSessionAttributeName(), client, webContext, sessionStore)
+ .retrieve(callContext, client.getStateSessionAttributeName(), client)
.orElse(null);
}
@@ -1219,7 +1233,7 @@ private String maybeOpenIdLogoutEndpoint(String idToken, String state, String po
return null;
}
- private String getFinalLogoutUrl(StaplerRequest req, Authentication auth) {
+ private String getFinalLogoutUrl(StaplerRequest2 req, Authentication auth) {
if (Jenkins.get().hasPermission(Jenkins.READ)) {
return super.getPostLogOutUrl2(req, auth);
}
@@ -1256,11 +1270,13 @@ private String buildOAuthRedirectUrl() throws NullPointerException {
* @param request The user's request
* @throws ParseException if the JWT (or other response) could not be parsed.
*/
- public void doFinishLogin(StaplerRequest request, StaplerResponse response) throws IOException, ParseException {
+ public void doFinishLogin(StaplerRequest2 request, StaplerResponse2 response) throws IOException, ParseException {
OidcClient client = buildOidcClient();
- WebContext webContext = JEEContextFactory.INSTANCE.newContext(request, response);
- SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore();
+ FrameworkParameters frameworkParameters = new JEEFrameworkParameters(request, response);
+ WebContext webContext = JEEContextFactory.INSTANCE.newContext(frameworkParameters);
+ SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore(frameworkParameters);
+ CallContext callContext = new CallContext(webContext, sessionStore);
try {
// NB: TODO this also handles back channel logout if "logoutendpoint" parameter is set
@@ -1273,14 +1289,13 @@ public void doFinishLogin(StaplerRequest request, StaplerResponse response) thro
throw new TechnicalException("Could not create a new session");
}
- Credentials credentials = client.getCredentials(webContext, sessionStore)
- .orElseThrow(() -> new Failure("Could not extract credentials from request"));
+ Credentials credentials = getCredentials(client, callContext);
ProfileCreator profileCreator = client.getProfileCreator();
// creating the profile performs validation of the token
OidcProfile profile = (OidcProfile) profileCreator
- .create(credentials, webContext, sessionStore)
+ .create(callContext, credentials)
.orElseThrow(() -> new Failure("Could not build user profile"));
AccessToken accessToken = profile.getAccessToken();
@@ -1314,6 +1329,15 @@ public void doFinishLogin(StaplerRequest request, StaplerResponse response) thro
}
}
+ private Credentials getCredentials(OidcClient client, CallContext callContext) {
+ Credentials credentials = client.getCredentials(callContext)
+ .orElseThrow(() -> new Failure("Could not extract credentials from request"));
+
+ return client.getAuthenticator()
+ .validate(callContext, credentials)
+ .orElseThrow(() -> new Failure("Could not " + "validate " + "credentials"));
+ }
+
/**
* Handles Token Expiration.
* @throws IOException a low level exception
@@ -1375,8 +1399,9 @@ public boolean handleTokenExpiration(HttpServletRequest httpRequest, HttpServlet
return true;
}
- private void redirectToLoginUrl(HttpServletRequest req, HttpServletResponse res) throws IOException {
- if (req != null && (req.getSession(false) != null || Strings.isNullOrEmpty(req.getHeader("Authorization")))) {
+ private void redirectToLoginUrl(@NonNull HttpServletRequest req, @NonNull HttpServletResponse res)
+ throws IOException {
+ if (req != null && req.getSession(false) != null || Strings.isNullOrEmpty(req.getHeader("Authorization"))) {
req.getSession().invalidate();
}
if (res != null) {
@@ -1388,7 +1413,6 @@ public boolean isExpired(OicCredentials credentials) {
if (credentials.getExpiresAtMillis() == null) {
return false;
}
-
return CLOCK.millis() >= credentials.getExpiresAtMillis();
}
@@ -1399,8 +1423,10 @@ private boolean refreshExpiredToken(
HttpServletResponse httpResponse)
throws IOException {
- WebContext webContext = JEEContextFactory.INSTANCE.newContext(httpRequest, httpResponse);
- SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore();
+ FrameworkParameters frameworkParameters = new JEEFrameworkParameters(httpRequest, httpResponse);
+ WebContext webContext = JEEContextFactory.INSTANCE.newContext(frameworkParameters);
+ SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore(frameworkParameters);
+ CallContext callContext = new CallContext(webContext, sessionStore);
OidcClient client = buildOidcClient();
// PAC4J maintains the nonce even though servers should not respond with an id token containing the nonce
// https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse
@@ -1416,7 +1442,7 @@ private boolean refreshExpiredToken(
profile.setIdTokenString(credentials.getIdToken());
profile.setRefreshToken(new RefreshToken(credentials.getRefreshToken()));
- profile = (OidcProfile) client.renewUserProfile(profile, webContext, sessionStore)
+ profile = (OidcProfile) client.renewUserProfile(callContext, profile)
.orElseThrow(() -> new IllegalStateException("Could not renew user profile"));
// During refresh the IDToken may or may not be present.
diff --git a/src/main/java/org/jenkinsci/plugins/oic/OicdPluginOpMetadataResolver.java b/src/main/java/org/jenkinsci/plugins/oic/OicdPluginOpMetadataResolver.java
new file mode 100644
index 00000000..84451124
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/oic/OicdPluginOpMetadataResolver.java
@@ -0,0 +1,37 @@
+package org.jenkinsci.plugins.oic;
+
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+import org.pac4j.oidc.config.OidcConfiguration;
+import org.pac4j.oidc.metadata.StaticOidcOpMetadataResolver;
+import org.pac4j.oidc.profile.creator.TokenValidator;
+
+public class OicdPluginOpMetadataResolver extends StaticOidcOpMetadataResolver {
+
+ private boolean allowsAnything;
+
+ public OicdPluginOpMetadataResolver(
+ OidcConfiguration configuration, OIDCProviderMetadata staticMetadata, boolean allowsAnything) {
+ super(configuration, staticMetadata);
+ this.allowsAnything = allowsAnything;
+ }
+
+ @Override
+ protected TokenValidator createTokenValidator() {
+ if (allowsAnything) {
+ return new AnythingGoesTokenValidator();
+ }
+
+ return super.createTokenValidator();
+ }
+
+ /**
+ * This method is needed as there seems to be a bug in pac4j and hasChanged is not able to return true
+ * This will make it work until the bug is fixed.
+ * Link to the bug: https://stackoverflow.com/questions/79126478/pac4j-returns-an-error-refreshing-an-expired-token
+ * TODO eventually remove
+ */
+ @Override
+ public boolean hasChanged() {
+ return true;
+ }
+}
diff --git a/src/test/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusionTest.java b/src/test/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusionTest.java
index e3155ef5..14b91baa 100644
--- a/src/test/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusionTest.java
+++ b/src/test/java/org/jenkinsci/plugins/oic/EscapeHatchCrumbExclusionTest.java
@@ -1,11 +1,11 @@
package org.jenkinsci.plugins.oic;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
diff --git a/src/test/java/org/jenkinsci/plugins/oic/MockHttpServletRequest.java b/src/test/java/org/jenkinsci/plugins/oic/MockHttpServletRequest.java
index 5bb2836a..578f0554 100644
--- a/src/test/java/org/jenkinsci/plugins/oic/MockHttpServletRequest.java
+++ b/src/test/java/org/jenkinsci/plugins/oic/MockHttpServletRequest.java
@@ -1,24 +1,24 @@
package org.jenkinsci.plugins.oic;
+import jakarta.servlet.AsyncContext;
+import jakarta.servlet.DispatcherType;
+import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import jakarta.servlet.http.HttpUpgradeHandler;
+import jakarta.servlet.http.Part;
import java.io.BufferedReader;
import java.security.Principal;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
-import javax.servlet.AsyncContext;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpUpgradeHandler;
-import javax.servlet.http.Part;
public class MockHttpServletRequest implements HttpServletRequest {
diff --git a/src/test/java/org/jenkinsci/plugins/oic/OicCrumbExclusionTest.java b/src/test/java/org/jenkinsci/plugins/oic/OicCrumbExclusionTest.java
index a6f0ad72..22ed2133 100644
--- a/src/test/java/org/jenkinsci/plugins/oic/OicCrumbExclusionTest.java
+++ b/src/test/java/org/jenkinsci/plugins/oic/OicCrumbExclusionTest.java
@@ -1,8 +1,8 @@
package org.jenkinsci.plugins.oic;
-import javax.servlet.FilterChain;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import jenkins.model.Jenkins;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
diff --git a/src/test/java/org/jenkinsci/plugins/oic/PluginTest.java b/src/test/java/org/jenkinsci/plugins/oic/PluginTest.java
index 4d2fcb34..2b502218 100644
--- a/src/test/java/org/jenkinsci/plugins/oic/PluginTest.java
+++ b/src/test/java/org/jenkinsci/plugins/oic/PluginTest.java
@@ -18,6 +18,7 @@
import hudson.model.User;
import hudson.tasks.Mailer;
import hudson.util.VersionNumber;
+import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
@@ -42,7 +43,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLException;
-import javax.servlet.http.HttpSession;
import jenkins.model.Jenkins;
import jenkins.security.ApiTokenProperty;
import jenkins.security.LastGrantedAuthoritiesProperty;
@@ -147,7 +147,7 @@ public void testLoginWithDefaults() throws Exception {
.withQueryParam("nonce", matching(".+")));
verify(postRequestedFor(urlPathEqualTo("/token")).withRequestBody(notMatching(".*&scope=.*")));
webClient.executeOnServer(() -> {
- HttpSession session = Stapler.getCurrentRequest().getSession();
+ HttpSession session = Stapler.getCurrentRequest2().getSession();
assertNotNull(((OicSecurityRealm) Jenkins.get().getSecurityRealm()).getStateAttribute(session));
return null;
});
@@ -983,7 +983,7 @@ public void testLogoutShouldBeJenkinsOnlyWhenNoProviderLogoutConfigured() throws
String[] logoutURL = new String[1];
jenkinsRule.executeOnServer(() -> {
- logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS2);
+ logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest2(), Jenkins.ANONYMOUS2);
return null;
});
assertEquals("/jenkins/", logoutURL[0]);
@@ -997,7 +997,7 @@ public void testLogoutShouldBeProviderURLWhenProviderLogoutConfigured() throws E
String[] logoutURL = new String[1];
jenkinsRule.executeOnServer(() -> {
- logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS2);
+ logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest2(), Jenkins.ANONYMOUS2);
return null;
});
assertEquals("http://provider/logout?state=null", logoutURL[0]);
@@ -1014,7 +1014,7 @@ public void testLogoutShouldBeProviderURLWithRedirectWhenProviderLogoutConfigure
String[] logoutURL = new String[1];
jenkinsRule.executeOnServer(() -> {
- logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS2);
+ logoutURL[0] = oicsr.getPostLogOutUrl2(Stapler.getCurrentRequest2(), Jenkins.ANONYMOUS2);
return null;
});
assertEquals(
diff --git a/src/test/java/org/jenkinsci/plugins/oic/TestRealm.java b/src/test/java/org/jenkinsci/plugins/oic/TestRealm.java
index eec1d58e..4abcd960 100644
--- a/src/test/java/org/jenkinsci/plugins/oic/TestRealm.java
+++ b/src/test/java/org/jenkinsci/plugins/oic/TestRealm.java
@@ -8,11 +8,13 @@
import java.io.IOException;
import java.io.ObjectStreamException;
import java.text.ParseException;
-import org.kohsuke.stapler.StaplerRequest;
-import org.kohsuke.stapler.StaplerResponse;
+import org.kohsuke.stapler.StaplerRequest2;
+import org.kohsuke.stapler.StaplerResponse2;
+import org.pac4j.core.context.FrameworkParameters;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.jee.context.JEEContextFactory;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import org.pac4j.jee.context.session.JEESessionStoreFactory;
import org.pac4j.oidc.client.OidcClient;
@@ -259,14 +261,15 @@ public Descriptor getDescriptor() {
}
@Override
- public void doFinishLogin(StaplerRequest request, StaplerResponse response) throws IOException, ParseException {
+ public void doFinishLogin(StaplerRequest2 request, StaplerResponse2 response) throws IOException, ParseException {
/*
* PluginTest uses a hardCoded nonce "nonce"
*/
if (!isNonceDisabled()) {
// only hack the nonce if the nonce is enabled
- WebContext webContext = JEEContextFactory.INSTANCE.newContext(request, response);
- SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore();
+ FrameworkParameters frameworkParameters = new JEEFrameworkParameters(request, response);
+ WebContext webContext = JEEContextFactory.INSTANCE.newContext(frameworkParameters);
+ SessionStore sessionStore = JEESessionStoreFactory.INSTANCE.newSessionStore(frameworkParameters);
OidcClient oidcClient = buildOidcClient();
sessionStore.set(webContext, oidcClient.getNonceSessionAttributeName(), "nonce");
}