[java-idp-oidc] branch main updated: JCOMOIDC-184 - Move OAuth2Client authentication flow from OP to oidc-common

Codeberg noreply at shibboleth.net
Fri Sep 18 14:19:36 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
https://codeberg.org/Shibboleth/java-idp-oidc/commit/ea45363371deea56745854d00fd39dbc39b28a4b

The following commit(s) were added to refs/heads/main by this push:
     new ea453633 JCOMOIDC-184 - Move OAuth2Client authentication flow from OP to oidc-common
ea453633 is described below

commit ea45363371deea56745854d00fd39dbc39b28a4b
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Sep 18 16:35:29 2026 +0300

    JCOMOIDC-184 - Move OAuth2Client authentication flow from OP to oidc-common
    
    https://shibboleth.atlassian.net/browse/JCOMOIDC-184
    
    Deleted content that was moved to java-oidc-common and java-idp-plugin-oidc-config modules.
---
 ...thenticationJWTPayloadClaimsAuditExtractor.java |  99 -----
 ...tAuthenticationJWTTypeHeaderAuditExtractor.java |  75 ----
 .../oidc/op/authn/audit/impl/package-info.java     |  16 -
 .../ExtractClientAuthenticationFromRequest.java    | 176 --------
 .../oidc/op/authn/impl/JWTCredentialValidator.java | 302 --------------
 .../impl/OIDCClientInfoCredentialValidator.java    | 177 --------
 .../impl/ValidateClientAuthenticationType.java     | 208 ----------
 .../plugin/oidc/op/authn/impl/package-info.java    |  19 -
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  20 -
 .../authn/OAuth2Client/OAuth2Client-beans.xml      | 295 --------------
 .../flows/authn/OAuth2Client/OAuth2Client-flow.xml |  43 --
 ...ExtractClientAuthenticationFromRequestTest.java | 206 ----------
 .../op/authn/impl/JWTCredentialValidatorTest.java  | 446 ---------------------
 .../OIDCClientInfoCredentialValidatorTest.java     | 159 --------
 .../impl/ValidateClientAuthenticationTypeTest.java | 159 --------
 15 files changed, 2400 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTPayloadClaimsAuditExtractor.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTPayloadClaimsAuditExtractor.java
deleted file mode 100644
index cfa7a0b1..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTPayloadClaimsAuditExtractor.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.audit.impl;
-
-import java.text.ParseException;
-import java.util.Date;
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.auth.JWTAuthentication;
-
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.shared.annotation.ParameterName;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
-
-/** {@link Function} that returns the desired claim from the client authentication JWT payload. */
-public class ClientAuthenticationJWTPayloadClaimsAuditExtractor implements Function<ProfileRequestContext, String> {
-
-    /** Strategy that will return {@link OAuth2ClientAuthenticationContext}. */
-    @Nonnull private Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> clientAuthContextLookupStrategy;
-
-    /** The claim whose value is to be extracted. */
-    @Nonnull @NotEmpty private final String key;
-
-    /**
-     * Constructor.
-     *
-     * @param claim Claim whose value is to be extracted
-     */
-    public ClientAuthenticationJWTPayloadClaimsAuditExtractor(
-            @Nonnull @NotEmpty @ParameterName(name = "key") final String claim) {
-        key = Constraint.isNotEmpty(claim, "The claim cannot be empty");
-        // PRC -> AuthenticationContext -> OAuth2ClientAuthenticationContext
-        final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> cacls =
-                new ChildContextLookup<>(OAuth2ClientAuthenticationContext.class).compose(
-                        new ChildContextLookup<>(AuthenticationContext.class));
-        assert cacls != null;
-        clientAuthContextLookupStrategy = cacls;
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param claim Claim whose value is to be extracted
-     * @param lookupStrategy Strategy that will return {@link OAuth2ClientAuthenticationContext}.
-     */
-    public ClientAuthenticationJWTPayloadClaimsAuditExtractor(
-            @Nonnull @NotEmpty @ParameterName(name = "key") final String claim,
-            @Nonnull @ParameterName(name = "clientAuthContextLookupStrategy")
-            final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> lookupStrategy) {
-        key = Constraint.isNotEmpty(claim, "key cannot be empty");
-        clientAuthContextLookupStrategy = 
-                Constraint.isNotNull(lookupStrategy, "clientAuthContextLookupStrategy lookup strategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public String apply(@Nullable final ProfileRequestContext input) {
-        final SignedJWT jwt =  Optional.ofNullable(clientAuthContextLookupStrategy.apply(input))
-                .map(ctx -> ctx.getClientAuthentication())
-                .filter(JWTAuthentication.class::isInstance)
-                .map(JWTAuthentication.class::cast)
-                .map(jwtAuthentication -> jwtAuthentication.getClientAssertion())
-                .orElse(null);
-        try {
-            final Object claim = jwt == null ? null : jwt.getJWTClaimsSet().getClaim(key);
-            if (claim instanceof Date date) {
-                return date.toInstant().toString();
-            } else if (claim != null) {
-                return claim.toString();
-            } else {
-                return null;
-            }
-        } catch (final ParseException e) {
-            return null;
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTTypeHeaderAuditExtractor.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTTypeHeaderAuditExtractor.java
deleted file mode 100644
index 11436813..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/ClientAuthenticationJWTTypeHeaderAuditExtractor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.audit.impl;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import com.nimbusds.oauth2.sdk.auth.JWTAuthentication;
-
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.shared.annotation.ParameterName;
-import net.shibboleth.shared.logic.Constraint;
-
-/** {@link Function} that returns the type header from the client authentication JWT payload. */
-public class ClientAuthenticationJWTTypeHeaderAuditExtractor implements Function<ProfileRequestContext, String> {
-
-    /** Strategy that will return {@link OAuth2ClientAuthenticationContext}. */
-    @Nonnull private Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> clientAuthContextLookupStrategy;
-
-    /**
-     * Constructor.
-     */
-    public ClientAuthenticationJWTTypeHeaderAuditExtractor() {
-        // PRC -> AuthenticationContext -> OAuth2ClientAuthenticationContext
-        final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> cacls =
-                new ChildContextLookup<>(OAuth2ClientAuthenticationContext.class).compose(
-                        new ChildContextLookup<>(AuthenticationContext.class));
-        assert cacls != null;
-        clientAuthContextLookupStrategy = cacls;
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param lookupStrategy Strategy that will return {@link OAuth2ClientAuthenticationContext}.
-     */
-    public ClientAuthenticationJWTTypeHeaderAuditExtractor(
-            @Nonnull @ParameterName(name = "clientAuthContextLookupStrategy")
-            final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> lookupStrategy) {
-        clientAuthContextLookupStrategy = 
-                Constraint.isNotNull(lookupStrategy, "clientAuthContextLookupStrategy lookup strategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public String apply(@Nullable final ProfileRequestContext input) {
-        return Optional.ofNullable(clientAuthContextLookupStrategy.apply(input))
-                .map(ctx -> ctx.getClientAuthentication())
-                .filter(JWTAuthentication.class::isInstance)
-                .map(JWTAuthentication.class::cast)
-                .map(jwtAuthentication -> jwtAuthentication.getClientAssertion())
-                .map(jwt -> jwt.getHeader().getType())
-                .map(joseType -> joseType.getType())
-                .orElse(null);
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/package-info.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/package-info.java
deleted file mode 100644
index 65ee5e57..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/audit/impl/package-info.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Package for audit extractors related to client authentication. */
-package net.shibboleth.idp.plugin.oidc.op.authn.audit.impl;
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequest.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequest.java
deleted file mode 100644
index ef0a65a5..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.util.Set;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
-
-import com.nimbusds.oauth2.sdk.AbstractOptionallyAuthenticatedRequest;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretPost;
-import com.nimbusds.oauth2.sdk.auth.TLSClientAuthentication;
-
-import net.shibboleth.idp.authn.AbstractExtractionAction;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.CertificateContext;
-import net.shibboleth.idp.authn.context.UsernamePasswordContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.oidc.profile.config.navigate.TokenEndpointAuthMethodLookupFunction;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-
-/**
- * Extracts OAuth 2 client authentication details from a request and stores them in an
- * {@link OAuth2ClientAuthenticationContext} beneath the {@link AuthenticationContext} for subsequent
- * validation.
- * 
- * <p>Depending on the form of authentication, additional child contexts may be created to store
- * extracted credentials, and they may undergo configured transformations. For example, password-based
- * methods will result in a {@link UsernamePasswordContext}, certificate-based in an {@link CertificateContext},
- * etc.</p>
- * 
- * @pre ProfileRequestContext.getSubcontext(AuthenticationContext.class) != null
- * @post AuthenticationContext.getSubcontext(OAuth2ClientAuthenticationContext.class) ! null
- *  along with other contexts as appropriate
- * @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#INVALID_MSG_CTX}
- * @event {@link AuthnEventIds#NO_CREDENTIALS}
- */
-public class ExtractClientAuthenticationFromRequest extends AbstractExtractionAction {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(ExtractClientAuthenticationFromRequest.class);
-
-    /** Lookup strategy for enabled client authentication methods. */
-    @NonnullAfterInit private Function<ProfileRequestContext, Set<ClientAuthenticationMethod>>
-        clientAuthMethodsLookupStrategy;
-
-    /** Message to extract credentials from. */
-    @Nullable private AbstractOptionallyAuthenticatedRequest request;
-
-    /**
-     * Constructor.
-     */
-    public ExtractClientAuthenticationFromRequest() {
-        clientAuthMethodsLookupStrategy = new TokenEndpointAuthMethodLookupFunction();
-    }
-
-    /**
-     * Set the lookup strategy for enabled client authentication methods.
-     *
-     * @param strategy What to set.
-     */
-    public void setClientAuthMethodsLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, Set<ClientAuthenticationMethod>> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-
-        clientAuthMethodsLookupStrategy = Constraint.isNotNull(strategy,
-                "Client authentication methods lookup strategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext) {
-        if (!super.doPreExecute(profileRequestContext, authenticationContext)) {
-            return false;
-        }
-        
-        if (profileRequestContext.getInboundMessageContext() != null) {
-            final Object msg = profileRequestContext.ensureInboundMessageContext().getMessage();
-            if (msg instanceof AbstractOptionallyAuthenticatedRequest aoar) {
-                request = aoar;
-                return true;
-            }
-        }
-        
-        log.warn("{} Inbound message missing or of incorrect type", getLogPrefix());
-        ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
-        return false;
-    }
-
-// Checkstyle: CyclomaticComplexity OFF
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext) {
-
-        assert request != null;
-        final ClientAuthentication clientAuthentication = request.getClientAuthentication();
-        
-        final OAuth2ClientAuthenticationContext ctx =
-                authenticationContext.ensureSubcontext(OAuth2ClientAuthenticationContext.class);
-        ctx.setClientAuthentication(clientAuthentication);
-
-        if (clientAuthentication == null) {
-            log.debug("{} No OAuth client credentials in request", getLogPrefix());
-            final Set<ClientAuthenticationMethod> methods =
-                    clientAuthMethodsLookupStrategy.apply(profileRequestContext);
-            //  Build event only if 'none' is not enabled in the profile configuration
-            if (methods == null || !methods.contains(ClientAuthenticationMethod.NONE)) {
-                ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
-            }
-            return;
-        }
-
-        // Note the Nimbus APIs appear to prevent the client ID or secret from being null.
-        
-        if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.equals(clientAuthentication.getMethod())) {
-            final ClientSecretBasic basic = (ClientSecretBasic) clientAuthentication;
-            if (basic.getClientID() != null && basic.getClientSecret() != null) {
-                final UsernamePasswordContext upContext = new UsernamePasswordContext();
-                upContext.setUsername(applyTransforms(basic.getClientID().getValue()))
-                    .setPassword(basic.getClientSecret().getValue());
-                authenticationContext.addSubcontext(upContext, true);
-            } else {
-                log.warn("{} No OAuth client credentials in basic-auth request?", getLogPrefix());
-                ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
-            }
-        } else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientAuthentication.getMethod())) {
-            final ClientSecretPost post = (ClientSecretPost) clientAuthentication;
-            if (post.getClientID() != null && post.getClientSecret() != null) {
-                final UsernamePasswordContext upContext = new UsernamePasswordContext();
-                upContext.setUsername(applyTransforms(post.getClientID().getValue()))
-                    .setPassword(post.getClientSecret().getValue());
-                authenticationContext.addSubcontext(upContext, true);
-            } else {
-                log.warn("{} No OAuth client credentials in POST request?", getLogPrefix());
-                ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
-            }
-        } else if (ClientAuthenticationMethod.TLS_CLIENT_AUTH.equals(clientAuthentication.getMethod()) ||
-                ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH.equals(clientAuthentication.getMethod())) {
-            final TLSClientAuthentication tls = (TLSClientAuthentication) clientAuthentication;
-            if (tls.getClientX509Certificate() != null) {
-                final CertificateContext certContext = new CertificateContext();
-                certContext.setCertificate(tls.getClientX509Certificate());
-                authenticationContext.addSubcontext(certContext, true);
-            }
-        }
-    }
-// Checkstyle: CyclomaticComplexity ON
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidator.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidator.java
deleted file mode 100644
index 67b545b5..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidator.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.text.ParseException;
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-import net.shibboleth.idp.authn.AbstractCredentialValidator;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.principal.UsernamePrincipal;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
-import net.shibboleth.oidc.jwt.claims.JWTValidationException;
-import net.shibboleth.oidc.profile.config.navigate.ClaimsValidatorLookupFunction;
-import net.shibboleth.oidc.profile.config.navigate.ClientAuthenticationJWTTypeLookupFunction;
-import net.shibboleth.oidc.security.jose.context.SecurityParametersContext;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.primitive.StringSupport;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.jwt.JWTClaimsSet;
-import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.auth.JWTAuthentication;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-
-/**
- * A validator that handles authentication via signed JWT.
- * 
- * <p>For now, implemented via Nimbus APIs.</p>
- * 
- * TODO: there will be additional validation checks added once implemented on the older branch
- */
- at ThreadSafeAfterInit
-public class JWTCredentialValidator extends AbstractCredentialValidator {
-    
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(JWTCredentialValidator.class);
-    
-    /** Strategy that will return {@link OAuth2ClientAuthenticationContext}. */
-    @Nonnull private Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> clientAuthContextLookupStrategy;
-
-    /** Strategy used to locate the {@link SecurityParametersContext} to use for verification. */
-    @Nonnull private Function<ProfileRequestContext,SecurityParametersContext> securityParametersLookupStrategy;
-
-    /** Strategy used to obtain {@link ClaimsValidator}. */
-    @Nonnull private Function<ProfileRequestContext,ClaimsValidator> claimsValidatorLookupStrategy;
-
-    /** Strategy used to fetch required JWT type header value. */
-    @Nonnull private Function<ProfileRequestContext,String> requiredJwtTypeHeaderLookupStrategy;
-
-    /** Whether to save the JWT in the Java Subject's public credentials. */
-    private boolean saveTokenToCredentialSet;
-    
-    /** Constructor. */
-    public JWTCredentialValidator() {
-        // PRC -> AuthenticationContext -> OAuth2ClientAuthenticationContext
-        final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> cacls =
-                new ChildContextLookup<>(OAuth2ClientAuthenticationContext.class).compose(
-                        new ChildContextLookup<>(AuthenticationContext.class));
-        assert cacls != null;
-        clientAuthContextLookupStrategy = cacls;
-        // PRC -> INBOUND -> SPC
-        final Function<ProfileRequestContext,SecurityParametersContext> spls =
-                new ChildContextLookup<>(SecurityParametersContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert spls != null;
-        securityParametersLookupStrategy = spls;
-        
-        claimsValidatorLookupStrategy = new ClaimsValidatorLookupFunction();
-        requiredJwtTypeHeaderLookupStrategy = new ClientAuthenticationJWTTypeLookupFunction();
-    }
-    
-    /**
-     * Set the strategy used to return the {@link OAuth2ClientAuthenticationContext}.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setOAuth2ClientAuthenticationLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,OAuth2ClientAuthenticationContext> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-    
-        clientAuthContextLookupStrategy =
-                Constraint.isNotNull(strategy, "OAuth2ClientAuthenticationContext lookup strategy cannot be null");
-    }
-    
-    /**
-     * Set the strategy used to locate the {@link SecurityParametersContext} to use.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setSecurityParametersLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,SecurityParametersContext> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-
-        securityParametersLookupStrategy =
-                Constraint.isNotNull(strategy, "SecurityParameterContext lookup strategy cannot be null");
-    }
-
-    /**
-     * Set the strategy used to locate {@link ClaimsValidator} used.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setClaimsValidatorLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,ClaimsValidator> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        
-        claimsValidatorLookupStrategy =
-                Constraint.isNotNull(strategy, "ClaimsValidator lookup strategy cannot be null");
-    }
-    
-    /**
-     * Set whether to save the JWT in the Java Subject's public credentials.
-     * 
-     * <p>Defaults to true</p>
-     * 
-     * @param flag flag to set
-     */
-    public void setSaveTokenToCredentialSet(final boolean flag) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        
-        saveTokenToCredentialSet = flag;
-    }
-
-    /**
-     * Set the strategy used to fetch required JWT type header value.
-     *
-     * @param strategy lookup strategy
-     *
-     * @since 4.3.0
-     */
-    public void setRequiredJwtTypeHeaderLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
-        checkSetterPreconditions();
-
-        requiredJwtTypeHeaderLookupStrategy =
-                Constraint.isNotNull(strategy, "RequiredJwtTypeHeaderLookupStrategy cannot be null");
-    }
-    
-// Checkstyle: CyclomaticComplexity OFF
-    /** {@inheritDoc} */
-    @Override
-    @Nullable protected Subject doValidate(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext,
-            @Nullable final WarningHandler warningHandler,
-            @Nullable final ErrorHandler errorHandler) throws Exception {
-        
-        final OAuth2ClientAuthenticationContext clientAuthContext =
-                clientAuthContextLookupStrategy.apply(profileRequestContext);
-        if (clientAuthContext == null) {
-            log.debug("{} No OAuth 2.0 client authentication information found", getLogPrefix());
-            return null;
-        }
-        
-        final ClientAuthentication clientAuth = clientAuthContext.getClientAuthentication();
-        if (clientAuth == null) {
-            log.debug("{} No OAuth 2.0 client authentication information found", getLogPrefix());
-            return null;
-        }
-        if (!ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(clientAuth.getMethod()) &&
-                !ClientAuthenticationMethod.PRIVATE_KEY_JWT.equals(clientAuth.getMethod())) {
-            log.debug("{} OAuth client authentication for '{}' of unsupported type: {}", getLogPrefix(),
-                    clientAuth.getClientID(), clientAuth.getMethod());
-            return null;
-        }
-        
-        if (!(clientAuth instanceof JWTAuthentication)) {
-            log.warn("{} OAuth client authentication object of unexpected type: {}", getLogPrefix(),
-                    clientAuth.getClass().getSimpleName());
-            log.info("{} Login by '{}' failed", getLogPrefix(), clientAuth.getClientID());
-            final LoginException e = new LoginException(AuthnEventIds.INVALID_CREDENTIALS); 
-            if (errorHandler != null) { 
-                errorHandler.handleError(profileRequestContext, authenticationContext, e,
-                        AuthnEventIds.INVALID_CREDENTIALS);
-            }
-            throw e;
-        }
-
-        final JWTAuthentication jwtAuth = (JWTAuthentication) clientAuth;
-        final SignedJWT clientAssertion = jwtAuth.getClientAssertion();
-        final ClientID clientId = clientAuth.getClientID();
-        assert clientAssertion != null;
-        assert clientId != null;
-        try {
-            validateJWTClaims(profileRequestContext, clientAssertion, clientId);
-        } catch (final Exception e) {
-            log.info("{} Login by '{}' failed", getLogPrefix(), clientAuth.getClientID());
-            if (errorHandler != null) { 
-                errorHandler.handleError(profileRequestContext, authenticationContext, e,
-                        AuthnEventIds.INVALID_CREDENTIALS);
-            }
-            throw e;
-        }
-        
-        log.info("{} Login by '{}' succeeded", getLogPrefix(), clientAuth.getClientID());
-        
-        return populateSubject(clientId, clientAssertion);
-    }    
-// Checkstyle: CyclomaticComplexity ON
-
-    /**
-     * Validates the contents of the given JWT against the requirements set in the OIDC core specification section 9.
-     * 
-     * @param jwt JWT to be validated
-     * @param clientId client ID from which the JWT is coming from
-     * @param profileRequestContext profile request context
-     * 
-     * @throws ParseException if unable to parse the claim set
-     * @throws JWTValidationException if the claims fail to validate
-     */
-    protected void validateJWTClaims(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final SignedJWT jwt, @Nonnull final ClientID clientId)
-                    throws ParseException, JWTValidationException {
-
-        final String requiredType = requiredJwtTypeHeaderLookupStrategy.apply(profileRequestContext);
-        if (StringSupport.trimOrNull(requiredType) != null) {
-            log.debug("{} Type header is required to be {}", getLogPrefix(), requiredType);
-            final String type = Optional.ofNullable(jwt.getHeader().getType())
-                    .map(joseType -> joseType.getType())
-                    .orElse(null);
-            if (!requiredType.equals(type)) {
-                log.warn("{} JWT validation failed for client '{}': Invalid JWT type header {}",
-                        getLogPrefix(), clientId, type);
-                throw new JWTValidationException("Invalid JWT type header " + type);
-            }
-        }
-
-        final ClaimsValidator validator = claimsValidatorLookupStrategy.apply(profileRequestContext);
-        if (validator == null) {
-            log.warn("{} JWT validation failed for client '{}': No ClaimsValidator found in configuration",
-                    getLogPrefix(), clientId);
-            throw new JWTValidationException("No ClaimsValidator found in configuration");
-        }
-        
-        final JWTClaimsSet claimsSet;
-        try {
-            claimsSet = jwt.getJWTClaimsSet();
-        } catch (final ParseException e) {
-            log.warn("{} Could not parse the JWT from client '{}' into claims set", getLogPrefix(), clientId);
-            throw e;
-        }
-
-        assert claimsSet != null;
-        try {
-            validator.validate(claimsSet, profileRequestContext);
-        } catch (final JWTValidationException e) {
-            log.warn("{} JWT validation failed for client '{}': {}", getLogPrefix(), clientId, e.getMessage());
-            throw e;
-        }
-    } 
-    
-   /**
-    * Builds a subject with "standard" content from the validation.
-    *
-    * @param clientId client ID
-    * @param token the token validated
-    * 
-    * @return the decorated subject
-    */
-   @Nonnull protected Subject populateSubject(@Nonnull @NotEmpty final ClientID clientId,
-           @Nonnull final SignedJWT token) {
-      
-       final Subject subject = new Subject();
-       final String clientIdValue = clientId.getValue();
-       if (clientIdValue != null) {
-           subject.getPrincipals().add(new UsernamePrincipal(clientIdValue));
-           if (saveTokenToCredentialSet) {
-               subject.getPublicCredentials().add(token);
-           }
-       }
-      
-       return super.populateSubject(subject);
-   }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidator.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidator.java
deleted file mode 100644
index 6a46b6d0..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidator.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-import net.shibboleth.idp.authn.AbstractUsernamePasswordCredentialValidator;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.UsernamePasswordContext;
-import net.shibboleth.idp.authn.principal.UsernamePrincipal;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
-import net.shibboleth.shared.codec.StringDigester;
-import net.shibboleth.shared.codec.StringDigester.OutputFormat;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.client.ClientMetadata;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
-
-/**
- * A password validator that authenticates against OIDC client metadata (which may itself be emulated
- * via SAML metadata).
- */
- at ThreadSafeAfterInit
-public class OIDCClientInfoCredentialValidator extends AbstractUsernamePasswordCredentialValidator {
-    
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(OIDCClientInfoCredentialValidator.class);
-    
-    /** Strategy that will return {@link OIDCMetadataContext}. */
-    @Nonnull private Function<ProfileRequestContext,OIDCMetadataContext> oidcMetadataContextLookupStrategy;
-    
-    /** Digester for SHA-1. */
-    @NonnullAfterInit private StringDigester digester;
-
-    /** Constructor. */
-    public OIDCClientInfoCredentialValidator() {
-        final Function<ProfileRequestContext,OIDCMetadataContext> omcls =
-                new ChildContextLookup<>(OIDCMetadataContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert omcls != null;
-        oidcMetadataContextLookupStrategy = omcls;
-    }
-    
-    /**
-     * Set the strategy used to return the {@link OIDCMetadataContext}.
-     * 
-     * @param strategy The lookup strategy.
-     */
-    public void setOidcMetadataContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,OIDCMetadataContext> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-    
-        oidcMetadataContextLookupStrategy =
-                Constraint.isNotNull(strategy, "OIDCMetadataContext lookup strategy cannot be null");
-    }
-    
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-
-        try {
-            digester = new StringDigester("SHA-256", OutputFormat.BASE64);
-        } catch (final NoSuchAlgorithmException e) {
-            throw new ComponentInitializationException("Error creating digester", e);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected Subject doValidate(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext,
-            @Nullable final WarningHandler warningHandler,
-            @Nullable final ErrorHandler errorHandler) throws Exception {
-
-        final OIDCMetadataContext oidcMetadataContext = oidcMetadataContextLookupStrategy.apply(profileRequestContext);
-        
-        if (oidcMetadataContext == null || oidcMetadataContext.getClientInformation() == null ) {
-            log.debug("{} OIDC client metadata is missing", getLogPrefix());
-            return null;
-        }
-
-        final OIDCClientInformation clientInformation = oidcMetadataContext.getClientInformation();
-        assert clientInformation != null;
-        final ClientMetadata clientMetadata = clientInformation.getMetadata();
-        assert clientMetadata != null;
-        if (ClientAuthenticationMethod.NONE.equals(clientMetadata.getTokenEndpointAuthMethod())) {
-            log.debug("{} OIDC client metadata contains 'none' type for endpoint authentication");
-            final Subject subject = new Subject();
-            final ClientID clientId = clientInformation.getID();
-            assert clientId != null;
-            final String clientIdValue = clientId.getValue();
-            if (clientIdValue != null) {
-                subject.getPrincipals().add(new UsernamePrincipal(applyTransforms(clientIdValue)));
-            }
-            return super.populateSubject(subject);
-        } else if (clientInformation.getSecret() == null) {
-            log.debug("{} OIDC client metadata for '{}' missing client secret", getLogPrefix(),
-                    clientInformation.getID());
-            return null;
-        }
-
-        return super.doValidate(profileRequestContext, authenticationContext, warningHandler, errorHandler);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @Nullable protected Subject doValidate(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext,
-            @Nonnull final UsernamePasswordContext usernamePasswordContext,
-            @Nullable final WarningHandler warningHandler,
-            @Nullable final ErrorHandler errorHandler) throws Exception {
-
-        final OIDCMetadataContext oidcMetadataContext = oidcMetadataContextLookupStrategy.apply(profileRequestContext);
-        if (oidcMetadataContext == null || oidcMetadataContext.getClientInformation() == null ) {
-            log.debug("{} OIDC client metadata is missing", getLogPrefix());
-            return null;
-        }
-
-        final OIDCClientInformation clientInformation = oidcMetadataContext.getClientInformation();
-        assert clientInformation != null;
-
-        final String username = usernamePasswordContext.getTransformedUsername();
-        log.debug("{} Attempting to authenticate effective client ID '{}' ", getLogPrefix(), username);
-        
-        final String secret = clientInformation.getSecret().getValue();
-        if (secret.startsWith("{SHA2}")) {
-            if (secret.substring(6).equals(digester.apply(usernamePasswordContext.getPassword()))) {
-                log.info("{} Login by '{}' succeeded", getLogPrefix(), username);
-                return populateSubject(new Subject(), usernamePasswordContext);
-            }
-        } else if (secret.equals(usernamePasswordContext.getPassword())) {
-            log.info("{} Login by '{}' succeeded", getLogPrefix(), username);
-            return populateSubject(new Subject(), usernamePasswordContext);
-        }
-        
-        log.info("{} Login by '{}' failed", getLogPrefix(), username);
-        
-        final LoginException e = new LoginException(AuthnEventIds.INVALID_CREDENTIALS); 
-        if (errorHandler != null) { 
-            errorHandler.handleError(profileRequestContext, authenticationContext, e,
-                    AuthnEventIds.INVALID_CREDENTIALS);
-        }
-        throw e;
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java
deleted file mode 100644
index b9539ffd..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
-
-import net.shibboleth.idp.authn.AbstractAuthenticationAction;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.oidc.profile.config.navigate.TokenEndpointAuthMethodLookupFunction;
-import net.shibboleth.shared.annotation.constraint.NonnullElements;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-
-/**
- * Validates the client authentication type with the token_endpoint_auth_method stored in the client's metadata
- * and the profile configuration.
- * 
- * <p>In the absence of metadata, the profile configuration is used alone.</p>
- * 
- * @pre {@link OIDCMetadataContext} is available
- * @pre AuthenticationContext.getSubcontext(OAuth2ClientAuthenticationContext.class) != null
- * @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#ACCESS_DENIED}
- */
-public class ValidateClientAuthenticationType extends AbstractAuthenticationAction {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(ValidateClientAuthenticationType.class);
-    
-    /** Strategy that will return {@link OIDCMetadataContext}. */
-    @Nonnull private Function<ProfileRequestContext,OIDCMetadataContext> oidcMetadataContextLookupStrategy;
-    
-    /** Strategy to obtain enabled token endpoint authentication methods. */
-    @Nonnull private Function<ProfileRequestContext,Set<ClientAuthenticationMethod>> 
-        tokenEndpointAuthMethodsLookupStrategy;
-    
-    /** The attached OIDC metadata context. */
-    @Nullable private OIDCMetadataContext oidcMetadataContext;
-
-    /** The extracted client authentication information. */
-    @Nullable private ClientAuthentication clientAuthentication;
-    
-    /** Enabled client authn methods. */
-    @Nullable @NonnullElements private Set<ClientAuthenticationMethod> enabledMethods;
-    
-    /**
-     * Constructor.
-     */
-    public ValidateClientAuthenticationType() {
-        final Function<ProfileRequestContext,OIDCMetadataContext> omcls =
-                new ChildContextLookup<>(OIDCMetadataContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert omcls != null;
-        oidcMetadataContextLookupStrategy = omcls;
-        tokenEndpointAuthMethodsLookupStrategy = new TokenEndpointAuthMethodLookupFunction();
-    }
-        
-    /**
-     * Set the strategy used to return the {@link OIDCMetadataContext}.
-     * 
-     * @param strategy The lookup strategy.
-     */
-    public void setOIDCMetadataContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, OIDCMetadataContext> strategy) {
-        checkSetterPreconditions();
-
-        oidcMetadataContextLookupStrategy =
-                Constraint.isNotNull(strategy, "OIDCMetadataContext lookup strategy cannot be null");
-    }
-    
-    /**
-     * Set strategy to obtain enabled token endpoint authentication methods.
-     * @param strategy What to set.
-     */
-    public void setTokenEndpointAuthMethodsLookupStrategy(@Nonnull final Function<ProfileRequestContext, 
-            Set<ClientAuthenticationMethod>> strategy) {
-        checkSetterPreconditions();
-
-        tokenEndpointAuthMethodsLookupStrategy = Constraint.isNotNull(strategy, 
-                "Strategy to obtain enabled token endpoint authentication methods cannot be null");
-        
-    }
-    
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext) {
-        if (!super.doPreExecute(profileRequestContext, authenticationContext)) {
-            return false;
-        }
-
-        final OAuth2ClientAuthenticationContext oauth2Ctx =
-                authenticationContext.getSubcontext(OAuth2ClientAuthenticationContext.class);
-        if (oauth2Ctx != null) {
-            clientAuthentication = oauth2Ctx.getClientAuthentication();
-        }
-
-        oidcMetadataContext = oidcMetadataContextLookupStrategy.apply(profileRequestContext);
-        
-        enabledMethods = tokenEndpointAuthMethodsLookupStrategy.apply(profileRequestContext);
-        if (enabledMethods == null) {
-            enabledMethods = Collections.emptySet();
-        }
-        
-        return true;
-    }
-    
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final AuthenticationContext authenticationContext) {
-        
-        final ClientAuthenticationMethod registeredMethod;
-
-        // Pull the client's registered authn method, or default to client_secret_basic.
-        // If no metadata exists, leave null.
-        if (oidcMetadataContext != null) {
-            final OIDCClientInformation clientInformation = oidcMetadataContext.getClientInformation();
-            if (clientInformation != null) {
-                final OIDCClientMetadata clientMetadata = clientInformation.getOIDCMetadata();
-                registeredMethod = clientMetadata.getTokenEndpointAuthMethod() != null ? 
-                        clientMetadata.getTokenEndpointAuthMethod() : ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
-            } else {
-                registeredMethod = null;
-            }
-        } else {
-            registeredMethod = null;
-        }
-
-        // Did the client use what it registered and is that still allowed?
-        // The enabledMethods member contains the methods authorized in the configuration as a whole.
-
-        final ClientAuthenticationMethod used =
-                clientAuthentication != null ? clientAuthentication.getMethod() : ClientAuthenticationMethod.NONE;
-
-        if (registeredMethod != null && !registeredMethod.equals(used)) {
-            log.warn("{} Client '{}' registered {} but attempted {}", getLogPrefix(), getClientID(),
-                    registeredMethod, used);
-            ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-            return;
-        }
-        assert enabledMethods != null;
-        if (!enabledMethods.contains(used)) {
-            log.warn("{} Requested method {} not enabled in profile configuration", getLogPrefix(), used);
-            ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-        }
-    }
-
-    /**
-     * Parses the client ID from OIDC metadata or client authentication, if exists.
-     * 
-     * @return client ID, or null it it couldn't be found.
-     */
-    @Nullable private String getClientID() {
-        if (oidcMetadataContext != null) {
-            final OIDCClientInformation clientInformation = oidcMetadataContext.getClientInformation();
-            if (clientInformation != null) {
-                return getClientIDValue(clientInformation.getID());
-            }
-        }
-        if (clientAuthentication != null) {
-            return getClientIDValue(clientAuthentication.getClientID());
-        }
-        return null;
-    }
-
-    /**
-     * Get the client ID value as string if the object is non-null.
-     *     
-     * @param clientId client ID, may be null.
-     * @return the client ID value.
-     */
-    @Nullable private String getClientIDValue(@Nullable final ClientID clientId) {
-        return clientId == null ? null : clientId.getValue();
-    }
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/package-info.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/package-info.java
deleted file mode 100644
index 20ad6130..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/package-info.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * Implementation classes supporting OIDC/OAuth client authentication.
- */
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index cd6daefd..d5d350e0 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -42,26 +42,6 @@
     <bean parent="shibboleth.AuthnComparisonRegistration"
         c:key-ref="shibboleth.OIDCAuthnMethodExact" c:value-ref="shibboleth.ExactMatchFactory" />
 
-    <!-- OAuth2 login flow -->
-    <bean p:id="authn/OAuth2Client" parent="shibboleth.AuthenticationFlow"
-            p:order="%{idp.authn.OAuth2Client.order:1000}"
-            p:nonBrowserSupported="true"
-            p:passiveAuthenticationSupported="true"
-            p:forcedAuthenticationSupported="true"
-            p:proxyRestrictionsEnforced="true"
-            p:proxyScopingEnforced="false"
-            p:discoveryRequired="false"
-            p:lifetime="PT60S"
-            p:inactivityTimeout="PT60S"
-            p:reuseCondition-ref="shibboleth.Conditions.FALSE"
-            p:activationCondition-ref="#{'%{idp.authn.OAuth2Client.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:subjectDecorator="#{getObject('%{idp.authn.OAuth2Client.subjectDecorator:}'.trim())}">
-        <property name="supportedPrincipalsByString">
-            <bean parent="shibboleth.CommaDelimStringArray"
-                c:_0="#{'%{idp.authn.OAuth2Client.supportedPrincipals:}'.trim()}" />
-        </property>
-    </bean>
-
     <!-- Property-based definition of login flows for OAuth endpoints. -->    
     <bean id="shibboleth.oidc.PotentialFlows" class="org.springframework.beans.factory.config.ListFactoryBean"
         p:sourceList="#{getObject('shibboleth.AuthenticationFlowDescriptorManager').getComponents().?[id matches 'authn/(' + '%{idp.oauth2.authn.flows:OAuth2Client}'.trim() + ')']}" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-beans.xml
deleted file mode 100644
index 797fcb55..00000000
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-beans.xml
+++ /dev/null
@@ -1,295 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-                           
-       default-init-method="initialize"
-       default-destroy-method="destroy">
-       
-    <!-- Default message map. -->
-    <util:map id="shibboleth.authn.OAuth2Client.ClassifiedMessageMap">
-        <entry key="RequestUnsupported">
-            <list>
-                <value>RequestUnsupported</value>
-            </list>
-        </entry>
-    </util:map>
-
-    <import resource="conditional:%{idp.home}/conf/authn/oauth2client-authn-config.xml" />
-
-    <bean id="ExtractClientAuthenticationFromRequest"
-        class="net.shibboleth.idp.plugin.oidc.op.authn.impl.ExtractClientAuthenticationFromRequest" scope="prototype"
-        p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier" />
-
-    <bean id="PopulateTokenEndpointJwtSignatureValidationParameters"
-            class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureValidationParameters"
-            scope="prototype"
-            c:strategy-ref="shibboleth.MessageContextLookup.Inbound">
-        <property name="configurationLookupStrategy">
-            <bean class="net.shibboleth.oidc.profile.config.navigate.JWTSignatureValidationConfigurationLookupFunction" />
-       </property>
-        <property name="signatureValidationParametersResolver">
-            <bean class="net.shibboleth.oidc.security.jose.impl.BasicSignatureValidationParametersResolver" />
-        </property>
-<!--         <property name="securityParametersContextLookupStrategy">
-            <bean parent="shibboleth.Functions.Compose"
-                c:g-ref="shibboleth.ChildLookupOrCreate.SecurityParameters"
-                c:f-ref="shibboleth.ChildLookup.RelyingParty" />
-        </property>
-        <property name="existingParametersContextLookupStrategy">
-            <bean parent="shibboleth.Functions.Compose"
-                c:g-ref="shibboleth.ChildLookup.SecurityParameters"
-                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
-        </property>-->
-    </bean>
-
-    <bean id="JWTAuthenticationCondition" parent="shibboleth.Conditions.Expression"
-        c:expression="#input.ensureSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).ensureSubcontext(T(net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext)).getClientAuthentication() instanceof T(com.nimbusds.oauth2.sdk.auth.JWTAuthentication)" />
-
-    <bean id="ValidateJWTSignature" class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor"
-        scope="prototype" c:executionDirection="INBOUND" p:activationCondition-ref="JWTAuthenticationCondition"
-        p:errorEvent="#{T(net.shibboleth.idp.authn.AuthnEventIds).AUTHN_EXCEPTION}">
-        <constructor-arg>
-            <bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain">
-                <property name="handlers">
-                    <list>
-                        <bean class="net.shibboleth.oidc.security.impl.CheckClientJWTSignatureAlgorithmHandler"
-                            scope="prototype" p:defaultAlgorithmValue="">
-                            <property name="jwtTokenLookupStrategy">
-                                <bean
-                                    class="net.shibboleth.profile.context.navigate.SpringExpressionContextLookupFunction"
-                                    c:_0="#{ T(org.opensaml.messaging.context.MessageContext) }"
-                                    c:outputType="#{T(com.nimbusds.jwt.SignedJWT)}"
-                                    c:expression="#input.getParent().ensureSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).ensureSubcontext(T(net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext)).getClientAuthentication().getClientAssertion()" />
-                            </property>
-                            <property name="clientInformationLookupStrategy">
-                                <bean
-                                    class="net.shibboleth.profile.context.navigate.SpringExpressionContextLookupFunction"
-                                    c:_0="#{ T(org.opensaml.messaging.context.MessageContext) }"
-                                    c:expression="#input.ensureSubcontext(T(net.shibboleth.oidc.metadata.context.OIDCMetadataContext)).getClientInformation()" />
-                            </property>
-                            <property name="signatureAlgorithmLookupStrategy">
-                                <bean
-                                    class="net.shibboleth.oidc.profile.config.navigate.ClientInformationStringValueLookupFunction"
-                                    c:keyName="token_endpoint_auth_signing_alg" />
-                            </property>
-                        </bean>
-                        <bean class="net.shibboleth.oidc.security.impl.JWTMessageSignatureSecurityHandler"
-                            scope="prototype">
-                            <property name="jwtTokenLookupStrategy">
-                                <bean
-                                    class="net.shibboleth.profile.context.navigate.SpringExpressionContextLookupFunction"
-                                    c:_0="#{ T(org.opensaml.messaging.context.MessageContext) }"
-                                    c:outputType="#{T(com.nimbusds.jwt.SignedJWT)}"
-                                    c:expression="#input.getParent().ensureSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).ensureSubcontext(T(net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext)).getClientAuthentication().getClientAssertion()" />
-                            </property>
-                            <property name="clientInformationLookupStrategy">
-                                <bean
-                                    class="net.shibboleth.profile.context.navigate.SpringExpressionContextLookupFunction"
-                                    c:_0="#{ T(org.opensaml.messaging.context.MessageContext) }"
-                                    c:expression="#input.ensureSubcontext(T(net.shibboleth.oidc.metadata.context.OIDCMetadataContext)).getClientInformation()" />
-                            </property>
-                        </bean>
-                    </list>
-                </property>
-            </bean>
-        </constructor-arg>
-    </bean>
-
-
-    <bean id="ValidateClientAuthenticationType"
-        class="net.shibboleth.idp.plugin.oidc.op.authn.impl.ValidateClientAuthenticationType" scope="prototype" />
-
-    <bean id="DefaultCleanupHook"
-        class="net.shibboleth.idp.authn.impl.ValidateCredentials.UsernamePasswordCleanupHook" />
-    
-    <bean id="ValidateCredentials"
-        class="net.shibboleth.idp.authn.impl.ValidateCredentials" scope="prototype"
-        p:requireAll="%{idp.authn.OAuth2Client.requireAll:false}"
-        p:validators="#{getObject('shibboleth.authn.OAuth2Client.Validators') ?: getObject('DefaultOAuth2ClientValidators')}"
-        p:addDefaultPrincipals="%{idp.authn.OAuth2Client.addDefaultPrincipals:true}"
-        p:supportedPrincipals="#{getObject('shibboleth.authn.OAuth2Client.PrincipalOverride')}"
-        p:classifiedMessages="#{getObject('shibboleth.authn.OAuth2Client.ClassifiedMessageMap')}"
-        p:cleanupHook="#{T(java.lang.Boolean).valueOf('%{idp.authn.OAuth2Client.removeAfterValidation:true}') ? getObject('DefaultCleanupHook') : null}"
-        p:lockoutManager="#{getObject('shibboleth.authn.OAuth2Client.AccountLockoutManager')}"
-        p:populateAuditContextAction="#{%{idp.authn.OAuth2Client.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.OAuth2Client.PopulateAuditContext') : null}"
-        p:writeAuditLogAction="#{%{idp.authn.OAuth2Client.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuthnAuditLog') : null}" />
-    
-    <bean id="PopulateSubjectCanonicalizationContext"
-        class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
-        p:availableFlows-ref="%{idp.authn.OAuth2Client.c14n.postLoginFlows:shibboleth.PostLoginSubjectCanonicalizationFlows}" />
-        
-    <!-- Default validators equivalent to previous versions. -->
-    
-    <util:list id="DefaultOAuth2ClientValidators">
-        <ref bean="shibboleth.OIDCClientInfoValidator" />
-        <ref bean="shibboleth.JWTValidator" />
-    </util:list>
-        
-    <!-- Validator parent beans -->
-
-    <bean id="shibboleth.CredentialValidator" abstract="true"
-        p:savePasswordToCredentialSet="%{idp.authn.OAuth2Client.retainAsPrivateCredential:false}" />
-
-    <bean id="shibboleth.OIDCClientInfoValidator" parent="shibboleth.CredentialValidator"
-        class="net.shibboleth.idp.plugin.oidc.op.authn.impl.OIDCClientInfoCredentialValidator"
-        p:id="oauth2-clientinfo" />
-        
-    <bean id="shibboleth.JWTValidator" class="net.shibboleth.idp.plugin.oidc.op.authn.impl.JWTCredentialValidator"
-        p:id="oauth2-jwt" />
-    
-    <bean id="shibboleth.JAASValidator" parent="shibboleth.CredentialValidator"
-        class="net.shibboleth.idp.authn.impl.JAASCredentialValidator" abstract="true"
-        p:id="oauth2-jaas" />
-
-    <bean id="shibboleth.KerberosValidator" parent="shibboleth.CredentialValidator"
-        class="net.shibboleth.idp.authn.impl.KerberosCredentialValidator" abstract="true"
-        p:id="oauth2-krb5" />
-
-    <bean id="shibboleth.LDAPValidator" parent="shibboleth.CredentialValidator" lazy-init="true"
-        class="net.shibboleth.idp.authn.impl.LDAPCredentialValidator"
-        p:id="oauth2-ldap"
-        p:authenticator-ref="shibboleth.authn.OAuth2Client.LDAP.authenticator" />
-
-    <bean id="shibboleth.HTPasswdValidator" abstract="true"
-        class="net.shibboleth.idp.authn.impl.HTPasswdCredentialValidator"
-        p:id="oauth2-htpasswd" />
-
-    <bean id="shibboleth.X509Validator" abstract="true"
-        class="net.shibboleth.idp.authn.impl.X509CertificateCredentialValidator"
-        p:id="oauth2-x509" />
-
-    <!-- Parent beans for custom ldaptive types. -->
-    
-    <bean id="shibboleth.authn.OAuth2Client.LDAP.authenticator" parent="shibboleth.LDAPAuthenticationFactory"
-        lazy-init="true" />
-
-    <bean id="shibboleth.X509ResourceCredentialConfig"
-        class="net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig" abstract="true" /> 
-    <bean id="shibboleth.KeystoreResourceCredentialConfig"
-        class="net.shibboleth.idp.authn.impl.KeystoreResourceCredentialConfig" abstract="true" /> 
-    
-    <bean id="shibboleth.authn.OAuth2Client.LDAP.trustCertificates" parent="shibboleth.X509ResourceCredentialConfig"
-        p:trustCertificates="%{idp.authn.OAuth2Client.LDAP.trustCertificates:undefined}" />
-    <bean id="shibboleth.authn.OAuth2Client.LDAP.truststore" parent="shibboleth.KeystoreResourceCredentialConfig"
-        p:truststore="%{idp.authn.OAuth2Client.LDAP.trustStore:undefined}" />
-
-    <bean id="shibboleth.LDAPAuthenticationFactory" abstract="true"
-        class="net.shibboleth.idp.authn.config.LDAPAuthenticationFactoryBean"
-        p:authenticatorType="#{'%{idp.authn.OAuth2Client.LDAP.authenticator:anonSearchAuthenticator}'.trim()}"
-        p:trustType="#{'%{idp.authn.OAuth2Client.LDAP.sslConfig:certificateTrust}'.trim()}"
-        p:connectionStrategyType="#{'%{idp.authn.OAuth2Client.LDAP.connectionStrategy:ACTIVE_PASSIVE}'.trim()}"
-        p:ldapUrl="%{idp.authn.OAuth2Client.LDAP.ldapURL:ldap://localhost:10389}"
-        p:useStartTLS="%{idp.authn.OAuth2Client.LDAP.useStartTLS:true}"
-        p:startTLSTimeout="%{idp.authn.OAuth2Client.LDAP.startTLSTimeout:PT3S}"
-        p:connectTimeout="%{idp.authn.OAuth2Client.LDAP.connectTimeout:PT3S}"
-        p:responseTimeout="%{idp.authn.OAuth2Client.LDAP.responseTimeout:PT3S}"
-        p:autoReconnect="%{idp.authn.OAuth2Client.LDAP.autoReconnect:true}"
-        p:reconnectTimeout="%{idp.authn.OAuth2Client.LDAP.reconnectTimeout:PT10S}"
-        p:trustCertificatesCredentialConfig-ref="shibboleth.authn.OAuth2Client.LDAP.trustCertificates"
-        p:truststoreCredentialConfig-ref="shibboleth.authn.OAuth2Client.LDAP.truststore"
-        p:disablePooling="%{idp.authn.OAuth2Client.LDAP.disablePooling:false}"
-        p:blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
-        p:minPoolSize="%{idp.pool.LDAP.minSize:3}"
-        p:maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
-        p:validateOnCheckout="%{idp.pool.LDAP.validateOnCheckout:false}"
-        p:validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
-        p:validatePeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"
-        p:validateDn="#{'%{idp.pool.LDAP.validateDN:}'.trim()}"
-        p:validateFilter="#{'%{idp.pool.LDAP.validateFilter:(objectClass=*)}'.trim()}"
-        p:bindPoolPassivatorType="#{'%{idp.authn.OAuth2Client.LDAP.bindPoolPassivator:none}'.trim()}"
-        p:prunePeriod="%{idp.pool.LDAP.prunePeriod:PT5M}"
-        p:idleTime="%{idp.pool.LDAP.idleTime:PT10M}"
-        p:dnFormat="%{idp.authn.OAuth2Client.LDAP.dnFormat:undefined}"
-        p:baseDn="#{'%{idp.authn.OAuth2Client.LDAP.baseDN:undefined}'.trim()}"
-        p:userFilter="#{'%{idp.authn.OAuth2Client.LDAP.userFilter:undefined}'.trim()}"
-        p:subtreeSearch="%{idp.authn.OAuth2Client.LDAP.subtreeSearch:false}"
-        p:resolveEntryOnFailure="%{idp.authn.OAuth2Client.LDAP.resolveEntryOnFailure:false}"
-        p:resolveEntryWithBindDn="%{idp.authn.OAuth2Client.LDAP.resolveEntryWithBindDN:false}"
-        p:velocityEngine-ref="shibboleth.VelocityEngine"
-        p:bindDn="#{'%{idp.authn.OAuth2Client.LDAP.bindDN:undefined}'.trim()}"
-        p:bindDnCredential="%{idp.authn.OAuth2Client.LDAP.bindDNCredential:undefined}"
-        p:usePasswordPolicy="%{idp.authn.OAuth2Client.LDAP.usePasswordPolicy:false}"
-        p:usePasswordExpiration="%{idp.authn.OAuth2Client.LDAP.usePasswordExpiration:false}"
-        p:activeDirectory="%{idp.authn.OAuth2Client.LDAP.activeDirectory:false}"
-        p:freeIPA="%{idp.authn.OAuth2Client.LDAP.freeIPADirectory:false}"
-        p:EDirectory="%{idp.authn.OAuth2Client.LDAP.eDirectory:false}"
-        p:accountStateExpirationPeriod="%{idp.authn.OAuth2Client.LDAP.accountStateExpirationPeriod:#{null}}"
-        p:accountStateWarningPeriod="%{idp.authn.OAuth2Client.LDAP.accountStateWarningPeriod:#{null}}"
-        p:accountStateLoginFailures="%{idp.authn.OAuth2Client.LDAP.accountStateLoginFailures:0}" />
-
-    <util:map id="shibboleth.authn.AuditFormattingMap">
-        <entry key="#{'%{idp.authn.OAuth2Client.audit.category:Shibboleth-Audit.OAuth2Client}'.trim()}"
-            value="#{'%{idp.authn.OAuth2Client.audit.format:%a|%T|%SP|%I|%s|%AF|%CV|%u|%tu|%AR|%UA}'.trim()}" />
-    </util:map>
-
-    <bean id="shibboleth.authn.OAuth2Client.PopulateAuditContext" parent="shibboleth.authn.AbstractPopulateAuditContext" lazy-init="true"
-        p:fieldExtractors="#{getObject('shibboleth.authn.OAuth2Client.AuditExtractors') ?: getObject('shibboleth.authn.OAuth2Client.DefaultAuditExtractors')}"/>
-
-     <bean id="shibboleth.authn.OAuth2Client.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
-            class="org.springframework.beans.factory.config.MapFactoryBean">
-        <property name="sourceMap">
-             <map merge="true">
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.idp.profile.IdPAuditFields.USERNAME"/>
-                    </key>
-                    <bean class="net.shibboleth.idp.authn.audit.impl.AttemptedUsernameAuditExtractor" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.idp.authn.AuthnAuditFields.TRANSFORMED_USERNAME"/>
-                    </key>
-                    <bean class="net.shibboleth.idp.authn.audit.impl.TransformedUsernameAuditExtractor" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.idp.saml.profile.SAMLAuditFields.REQUEST_ID"/>
-                    </key>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="jti" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.idp.saml.profile.SAMLAuditFields.REQUEST_ISSUE_INSTANT"/>
-                    </key>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="iat" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.audit.AuditFields.AUDIENCE"/>
-                    </key>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="aud" />
-                </entry>
-                <entry key="iss">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="iss" />
-                </entry>
-                <entry key="sub">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="sub" />
-                </entry>
-                <entry key="exp">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="exp" />
-                </entry>
-                <entry key="iat">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTPayloadClaimsAuditExtractor"
-                        c:key="iat" />
-                </entry>
-                <entry key="typ">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.authn.audit.impl.ClientAuthenticationJWTTypeHeaderAuditExtractor" />
-                </entry>
-             </map>
-        </property>
-    </bean>
- 
-</beans>
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-flow.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-flow.xml
deleted file mode 100644
index a75eb608..00000000
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OAuth2Client/OAuth2Client-flow.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<flow xmlns="http://www.springframework.org/schema/webflow"
-      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-      xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
-      parent="authn.abstract">
-
-    <!--
-    This is a login flow for handling OAuth2-defined client authentication mechanisms.
-    The current implementation relies on Nimbus APIs but could be replaced in the future if necessary.
-    -->
-
-    <action-state id="OAuth2Client">
-        <evaluate expression="PopulateTokenEndpointJwtSignatureValidationParameters"/>
-        <evaluate expression="ExtractClientAuthenticationFromRequest" />
-        <evaluate expression="ValidateClientAuthenticationType" />
-        <evaluate expression="ValidateJWTSignature"/>
-        <evaluate expression="ValidateCredentials" />
-        <evaluate expression="PopulateSubjectCanonicalizationContext" />
-        <evaluate expression="'proceed'" />
-        
-        <transition on="proceed" to="CallSubjectCanonicalization" />
-    </action-state>
-    
-    <!-- This runs a c14n step on the result of the authentication. -->
-    <subflow-state id="CallSubjectCanonicalization" subflow="c14n">
-        <input name="calledAsSubflow" value="true" />
-        <transition on="proceed" to="proceed" />
-        
-        <!-- This shouldn't generally happen, but if c14n fails, it's allowable to fall through. -->
-        <transition on="SubjectCanonicalizationError" to="ReselectFlow" />
-    </subflow-state>
-
-    <!-- As a "fall-through" method, remap selected events to select a different flow. -->
-    <global-transitions>
-        <transition on="NoCredentials" to="ReselectFlow" />
-        <transition on="InvalidCredentials" to="ReselectFlow" />
-        <transition on="RequestUnsupported" to="ReselectFlow" />
-        <transition on="UnknownUsername" to="ReselectFlow" />
-        <transition on="AccessDenied" to="ReselectFlow" />
-    </global-transitions>
-
-    <bean-import resource="OAuth2Client-beans.xml" />
-
-</flow>
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequestTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequestTest.java
deleted file mode 100644
index 3f0c7492..00000000
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ExtractClientAuthenticationFromRequestTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.jose.JWSAlgorithm;
-import com.nimbusds.oauth2.sdk.AuthorizationCode;
-import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
-import com.nimbusds.oauth2.sdk.AuthorizationGrant;
-import com.nimbusds.oauth2.sdk.TokenRequest;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretJWT;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretPost;
-import com.nimbusds.oauth2.sdk.auth.PrivateKeyJWT;
-import com.nimbusds.oauth2.sdk.auth.Secret;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.UsernamePasswordContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
-import net.shibboleth.idp.profile.testing.ActionTestingSupport;
-import net.shibboleth.idp.profile.testing.RequestContextBuilder;
-
-/**
- * Unit tests for {@link ExtractClientAuthenticationFromRequest}.
- */
-public class ExtractClientAuthenticationFromRequestTest {
-    
-    private ClientID clientId;
-    private Secret clientSecret;
-    
-    private URI endpointUri;
-    
-    private RSAPrivateKey rsaPrivateKey;
-    
-    private ExtractClientAuthenticationFromRequest action;
-    
-    private RequestContext rc;
-    private ProfileRequestContext prc;
-    
-    @BeforeClass
-    public void initKeys() throws NoSuchAlgorithmException {
-        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
-        keyGen.initialize(2048);
-        final KeyPair keyPair = keyGen.genKeyPair();
-        rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
-    }
-
-    @BeforeMethod
-    public void init() throws URISyntaxException, ComponentInitializationException {
-        clientId = new ClientID("mockId");
-        clientSecret = new Secret("secret1234567890secret1234567890secret1234567890");
-        endpointUri = new URI("https://mock.example.org/");
-        
-        action = new ExtractClientAuthenticationFromRequest();
-        action.initialize();
-    }
-    
-    protected void initializeRequestCtx(final ClientAuthenticationMethod method)
-            throws JOSEException, ComponentInitializationException {
-        final ClientAuthentication clientAuth;
-        if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) {
-            clientAuth = new ClientSecretBasic(clientId, clientSecret);
-        } else if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_POST)) {
-            clientAuth = new ClientSecretPost(clientId, clientSecret);
-        } else if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_JWT)) {
-            clientAuth = new ClientSecretJWT(clientId, endpointUri, JWSAlgorithm.HS256, clientSecret);
-        } else if (method.equals(ClientAuthenticationMethod.PRIVATE_KEY_JWT)) {
-            clientAuth = new PrivateKeyJWT(clientId, endpointUri, JWSAlgorithm.RS256, (PrivateKey) rsaPrivateKey, null,
-                    null);
-        } else {
-            clientAuth = null;
-        }
-        final AuthorizationGrant authzGrant = new AuthorizationCodeGrant(new AuthorizationCode(), null);
-        
-        rc = new RequestContextBuilder()
-                .setInboundMessage(new TokenRequest(null, clientAuth, authzGrant, null))
-                .buildRequestContext();
-        prc = new WebflowRequestContextProfileRequestContextLookup().apply(rc);
-        prc.addSubcontext(new AuthenticationContext());
-    }
-
-    @Test
-    public void testNoAuthnContext() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        prc.removeSubcontext(AuthenticationContext.class);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertEvent(e, AuthnEventIds.INVALID_AUTHN_CTX);
-    }
-
-    @Test
-    public void testBasic() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-        
-        final OAuth2ClientAuthenticationContext oauth =
-                prc.ensureSubcontext(AuthenticationContext.class).getSubcontext(OAuth2ClientAuthenticationContext.class);
-        Assert.assertNotNull(oauth);
-        assert oauth != null;
-        final ClientAuthentication clientAuthentication = oauth.getClientAuthentication();
-        assert clientAuthentication != null;
-        Assert.assertEquals(clientAuthentication.getClientID(), clientId);
-        Assert.assertEquals(clientAuthentication.getMethod(), ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        final UsernamePasswordContext up = prc.ensureSubcontext(AuthenticationContext.class)
-                .getSubcontext(UsernamePasswordContext.class);
-        Assert.assertNotNull(up);
-        assert up != null;
-        Assert.assertEquals(up.getUsername(), clientId.getValue());
-        Assert.assertEquals(up.getPassword(), clientSecret.getValue());
-    }
-
-    @Test
-    public void testPost() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_POST);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-        
-        final OAuth2ClientAuthenticationContext oauth =
-                prc.ensureSubcontext(AuthenticationContext.class).getSubcontext(OAuth2ClientAuthenticationContext.class);
-        Assert.assertNotNull(oauth);
-        assert oauth != null;
-        final ClientAuthentication clientAuthentication = oauth.getClientAuthentication();
-        assert clientAuthentication != null;
-        Assert.assertEquals(clientAuthentication.getClientID(), clientId);
-        Assert.assertEquals(clientAuthentication.getMethod(), ClientAuthenticationMethod.CLIENT_SECRET_POST);
-        final UsernamePasswordContext up = prc.ensureSubcontext(AuthenticationContext.class)
-                .getSubcontext(UsernamePasswordContext.class);
-        Assert.assertNotNull(up);
-        assert up != null;
-        Assert.assertEquals(up.getUsername(), clientId.getValue());
-        Assert.assertEquals(up.getPassword(), clientSecret.getValue());
-    }
-
-    @Test
-    public void testSecretJwt() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_JWT);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-        
-        final OAuth2ClientAuthenticationContext oauth =
-                prc.ensureSubcontext(AuthenticationContext.class).getSubcontext(OAuth2ClientAuthenticationContext.class);
-        Assert.assertNotNull(oauth);
-        assert oauth != null;
-        final ClientAuthentication clientAuthentication = oauth.getClientAuthentication();
-        assert clientAuthentication != null;
-        Assert.assertEquals(clientAuthentication.getClientID(), clientId);
-        Assert.assertEquals(clientAuthentication.getMethod(), ClientAuthenticationMethod.CLIENT_SECRET_JWT);
-        final UsernamePasswordContext up = prc.ensureSubcontext(AuthenticationContext.class)
-                .getSubcontext(UsernamePasswordContext.class);
-        Assert.assertNull(up);
-    }
-
-    @Test
-    public void testPrivateKeyJwt() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.PRIVATE_KEY_JWT);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-
-        final OAuth2ClientAuthenticationContext oauth =
-                prc.ensureSubcontext(AuthenticationContext.class).getSubcontext(OAuth2ClientAuthenticationContext.class);
-        Assert.assertNotNull(oauth);
-        assert oauth != null;
-        final ClientAuthentication clientAuthentication = oauth.getClientAuthentication();
-        assert clientAuthentication != null;
-        Assert.assertEquals(clientAuthentication.getClientID(), clientId);
-        Assert.assertEquals(clientAuthentication.getMethod(), ClientAuthenticationMethod.PRIVATE_KEY_JWT);
-        final UsernamePasswordContext up = prc.ensureSubcontext(AuthenticationContext.class)
-                .getSubcontext(UsernamePasswordContext.class);
-        Assert.assertNull(up);
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidatorTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidatorTest.java
deleted file mode 100644
index abe32f7f..00000000
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/JWTCredentialValidatorTest.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.time.Instant;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.function.Function;
-
-import org.mockito.Mockito;
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.storage.ReplayCache;
-import org.opensaml.storage.impl.MemoryStorageService;
-import org.opensaml.storage.impl.StorageServiceReplayCache;
-import org.springframework.webflow.execution.Event;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.jose.JOSEObjectType;
-import com.nimbusds.jose.JWSAlgorithm;
-import com.nimbusds.jose.JWSHeader;
-import com.nimbusds.jose.crypto.MACSigner;
-import com.nimbusds.jose.crypto.RSASSASigner;
-import com.nimbusds.jwt.JWTClaimsSet;
-import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.AuthorizationCode;
-import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
-import com.nimbusds.oauth2.sdk.AuthorizationGrant;
-import com.nimbusds.oauth2.sdk.TokenRequest;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretJWT;
-import com.nimbusds.oauth2.sdk.auth.PrivateKeyJWT;
-import com.nimbusds.oauth2.sdk.auth.Secret;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
-
-import jakarta.servlet.http.HttpServletRequest;
-import net.shibboleth.idp.authn.AuthenticationResult;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.impl.ValidateCredentials;
-import net.shibboleth.idp.authn.impl.testing.BaseAuthenticationContextTest;
-import net.shibboleth.idp.authn.principal.UsernamePrincipal;
-import net.shibboleth.idp.profile.testing.ActionTestingSupport;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.oidc.profile.oauth2.config.impl.AbstractOAuth2ClientAuthenticableProfileConfiguration;
-import net.shibboleth.oidc.profile.oauth2.config.impl.DefaultOAuth2TokenConfiguration;
-import net.shibboleth.oidc.security.jose.context.SecurityParametersContext;
-import net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator;
-import net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator;
-import net.shibboleth.oidc.security.jwt.claims.impl.ExactMatchClaimsValidator;
-import net.shibboleth.oidc.security.jwt.claims.impl.ExpiryClaimsValidator;
-import net.shibboleth.oidc.security.jwt.claims.impl.IssuedAtClaimsValidator;
-import net.shibboleth.oidc.security.jwt.claims.impl.JWTIdentifierClaimsValidator;
-import net.shibboleth.profile.context.RelyingPartyContext;
-import net.shibboleth.profile.context.navigate.RelyingPartyIdLookupFunction;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.BiFunctionSupport;
-
-/**
- * Unit tests for {@link JWTCredentialValidator}.
- */
-public class JWTCredentialValidatorTest extends BaseAuthenticationContextTest {
-    
-    ClientID clientId;
-    Secret clientSecret;
-    
-    URI endpointUri;
-    
-    RSAPrivateKey rsaPrivateKey;
-    RSAPublicKey rsaPublicKey;
-
-    private ClaimsValidator claimsValidator;
-    private JWTCredentialValidator validator;
-    private ValidateCredentials action;
-
-    @SuppressWarnings("unchecked")
-    private Function<ProfileRequestContext, String> typeHeaderLookup = Mockito.mock(Function.class);
-
-    @BeforeClass
-    public void initKeys() throws NoSuchAlgorithmException {
-        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
-        keyGen.initialize(2048);
-        final KeyPair keyPair = keyGen.genKeyPair();
-        rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
-        rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
-    }
-    
-    @Override
-    @BeforeMethod
-    public void setUp() throws ComponentInitializationException {
-        super.setUp();
-        
-        clientId = new ClientID("mockId");
-        clientSecret = new Secret("secret1234567890secret1234567890secret1234567890");
-        try {
-            endpointUri = new URI("http://localhost");
-        } catch (final URISyntaxException e) {
-            throw new ComponentInitializationException(e);
-        }
-
-        final StorageServiceReplayCache replayCache = new StorageServiceReplayCache();
-        final MemoryStorageService storageService = new MemoryStorageService();
-        storageService.setId("mockId");
-        storageService.initialize();
-        replayCache.setStorage(storageService);
-        
-        claimsValidator =
-                constructClaimsValidator((HttpServletRequest) src.getExternalContext().getNativeRequest(), replayCache);
-        final DefaultOAuth2TokenConfiguration profile = new DefaultOAuth2TokenConfiguration();
-        profile.setClaimsValidator(claimsValidator);
-        prc.ensureSubcontext(RelyingPartyContext.class).setProfileConfig(profile);
-        
-        validator = new JWTCredentialValidator();
-        validator.setId("test");
-        validator.setSecurityParametersLookupStrategy(new ChildContextLookup<>(SecurityParametersContext.class));
-        validator.setRequiredJwtTypeHeaderLookupStrategy(typeHeaderLookup);
-        validator.initialize();
-        
-        action = new ValidateCredentials();
-        action.setValidators(Collections.singletonList(validator));
-        action.initialize();
-    }
-    
-    protected void completeSetup(final TokenRequest request, final ClientAuthenticationMethod storedMethod,
-            final boolean sameSecret) throws NoSuchAlgorithmException, JOSEException {
-
-        final OIDCMetadataContext oidcContext = new OIDCMetadataContext();
-        final OIDCClientMetadata metadata = new OIDCClientMetadata();
-        metadata.setTokenEndpointAuthMethod(storedMethod);
-        
-        final OIDCClientInformation clientInformation = 
-                new OIDCClientInformation(clientId, new Date(), metadata, clientSecret);
-        oidcContext.setClientInformation(clientInformation);
-        prc.ensureInboundMessageContext().addSubcontext(oidcContext);
-    }
-    
-    protected void initializeTokenRequest(final ClientAuthenticationMethod method, final SignedJWT jwt,
-            final boolean sameSecret) throws JOSEException, NoSuchAlgorithmException {
-
-        final ClientAuthentication clientAuth;
-        if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_JWT)) {
-            clientAuth = new ClientSecretJWT(jwt);
-        } else if (method.equals(ClientAuthenticationMethod.PRIVATE_KEY_JWT)) {
-            clientAuth = new PrivateKeyJWT(jwt);
-        } else {
-            clientAuth = null;
-        }
-
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        ac.setAttemptedFlow(authenticationFlows.get(0));
-        ac.ensureSubcontext(OAuth2ClientAuthenticationContext.class).setClientAuthentication(clientAuth);
-        
-        prc.ensureSubcontext(RelyingPartyContext.class).setRelyingPartyId(clientId.getValue());
-        
-        final AuthorizationGrant authzGrant = new AuthorizationCodeGrant(new AuthorizationCode(), null);
-        completeSetup(new TokenRequest(null, clientAuth, authzGrant, null), method, sameSecret);
-    }
-    
-    protected ClaimsValidator constructClaimsValidator(final HttpServletRequest httpRequest,
-            final ReplayCache replayCache) {
-        final ChainingJWTClaimsValidator claimsValidation = new ChainingJWTClaimsValidator();
-        final ExpiryClaimsValidator expValidator = new ExpiryClaimsValidator();
-        final IssuedAtClaimsValidator iatValidator = new IssuedAtClaimsValidator();
-        iatValidator.setRequiredRule(false);
-        final ExactMatchClaimsValidator issValidator = new ExactMatchClaimsValidator();
-        issValidator.setClaimName("iss");
-        issValidator.setValueToMatchLookupStrategy(
-                BiFunctionSupport.forFunctionOfFirstArg(new RelyingPartyIdLookupFunction()));
-        final ExactMatchClaimsValidator subValidator = new ExactMatchClaimsValidator();
-        subValidator.setClaimName("sub");
-        subValidator.setValueToMatchLookupStrategy(
-                BiFunctionSupport.forFunctionOfFirstArg(new RelyingPartyIdLookupFunction()));
-        final AudienceClaimsValidator audValidator = new AudienceClaimsValidator();
-        audValidator.setAudienceLookupStrategy((prc, claims) -> httpRequest.getRequestURL().toString());
-        final JWTIdentifierClaimsValidator jitValidator = new JWTIdentifierClaimsValidator();
-        assert replayCache != null;
-        jitValidator.setReplayCache(replayCache);
-        claimsValidation.setClaimValidators(List.of(expValidator, iatValidator, issValidator, subValidator,
-                audValidator, jitValidator));
-        return claimsValidation;
-    }
-    
-    protected void testFailingJwtAuth(final ClientAuthenticationMethod method, final SignedJWT jwt,
-            final boolean replay, final boolean sameSecret) throws Exception {
-        initializeTokenRequest(method, jwt, sameSecret);
-        
-        Event event = action.execute(src);
-        if (replay) {
-            ActionTestingSupport.assertProceedEvent(event);
-            event = action.execute(src);
-        }
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_CREDENTIALS);
-    }
-
-    protected JWTClaimsSet claimsSetWithIatInTheFuture() {
-        return new JWTClaimsSet.Builder()
-                .subject(clientId.toString())
-                .issuer(clientId.toString())
-                .audience(endpointUri.toString())
-                .expirationTime(Date.from(Instant.now().plusSeconds(600)))
-                .issueTime(Date.from(Instant.now().plusSeconds(600)))
-                .jwtID("mockId")
-                .build();
-    }
-    
-    protected JWTClaimsSet claimsSetWithExpInThePast() {
-        return new JWTClaimsSet.Builder()
-                .subject(clientId.toString())
-                .issuer(clientId.toString())
-                .audience(endpointUri.toString())
-                .expirationTime(Date.from(Instant.now().minusSeconds(600)))
-                .issueTime(Date.from(Instant.now()))
-                .jwtID("mockId")
-                .build();
-    }
-    
-    protected JWTClaimsSet claimsSetWithoutJit() {
-        return new JWTClaimsSet.Builder()
-                .subject(clientId.toString())
-                .issuer(clientId.toString())
-                .audience(endpointUri.toString())
-                .expirationTime(Date.from(Instant.now().plusSeconds(600)))
-                .issueTime(Date.from(Instant.now()))
-                .build();
-    }
-
-    protected JWTClaimsSet validClaimsSet() {
-        return new JWTClaimsSet.Builder()
-                .subject(clientId.toString())
-                .issuer(clientId.toString())
-                .audience(endpointUri.toString())
-                .expirationTime(Date.from(Instant.now().plusSeconds(600)))
-                .issueTime(Date.from(Instant.now()))
-                .jwtID("mockId")
-                .build();
-    }
-    
-    protected SignedJWT createSecretJWT(final JWTClaimsSet claimsSet) throws JOSEException {
-        return createSecretJWT(claimsSet, clientSecret.getValue());
-    }
-
-    protected SignedJWT createSecretJWT(final JWTClaimsSet claimsSet, final String clientSecret)
-            throws JOSEException {
-        return createSecretJWT(claimsSet, clientSecret, null);
-    }
-
-    protected SignedJWT createSecretJWT(final JWTClaimsSet claimsSet, final String clientSecret,
-            final String typeHeader) throws JOSEException {
-        final SignedJWT jwt;
-        if (typeHeader == null) {
-            jwt = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
-        } else {
-            jwt = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.HS256)
-                    .type(new JOSEObjectType(typeHeader)).build(), claimsSet);
-        }
-        final MACSigner signer = new MACSigner(clientSecret);
-        jwt.sign(signer);
-        return jwt;
-    }
-
-    protected SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet) throws JOSEException {
-        final SignedJWT jwt = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);
-        final RSASSASigner signer = new RSASSASigner(rsaPrivateKey);
-        jwt.sign(signer);
-        return jwt;
-    }
-
-    protected SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet, final String header) throws JOSEException {
-        final SignedJWT jwt = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256)
-                .type(new JOSEObjectType(header)).build(), claimsSet);
-        final RSASSASigner signer = new RSASSASigner(rsaPrivateKey);
-        jwt.sign(signer);
-        return jwt;
-    }
-
-    @Test
-    public void testNoClaimsValidator() throws Exception {
-        ((AbstractOAuth2ClientAuthenticableProfileConfiguration) prc.ensureSubcontext(
-                RelyingPartyContext.class).ensureProfileConfig()).setClaimsValidator(null);
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(validClaimsSet()), false, true);
-    }
-    
-    @Test
-    public void testSecretJwt() throws JOSEException, NoSuchAlgorithmException {
-        initializeTokenRequest(ClientAuthenticationMethod.CLIENT_SECRET_JWT, createSecretJWT(validClaimsSet()), true);
-
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(null);
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-
-    @Test
-    public void testSecretJwt_enforcedHeader() throws JOSEException, NoSuchAlgorithmException {
-        final String header = "enforcedTypeHeader";
-        initializeTokenRequest(ClientAuthenticationMethod.CLIENT_SECRET_JWT, createSecretJWT(validClaimsSet(),
-                clientSecret.toString(), header), true);
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(header);
-
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-
-
-    @Test
-    public void testSecretJwt_missingMandatoryHeader() throws Exception {
-        final String header = "enforcedTypeHeader";
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(header);
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(validClaimsSet()), false, true);
-    }
-
-    @Test
-    public void testPrivateKeyJwt() throws JOSEException, NoSuchAlgorithmException {
-        initializeTokenRequest(ClientAuthenticationMethod.PRIVATE_KEY_JWT, createPrivateKeyJWT(validClaimsSet()), true);
-        
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(null);
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-
-    @Test
-    public void testPrivateKeyJwt_enforcedHeader() throws JOSEException, NoSuchAlgorithmException {
-        final String header = "enforcedTypeHeader";
-        initializeTokenRequest(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(validClaimsSet(), header), true);
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(header);
-        
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-
-    @Test
-    public void testPrivateKeyJwt_missingMandatoryHeader() throws Exception {
-        final String header = "enforcedTypeHeader";
-        Mockito.when(typeHeaderLookup.apply(Mockito.any())).thenReturn(header);
-        testFailingJwtAuth(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(validClaimsSet()), false, true);
-    }
-
-    @Test
-    public void testInvalidSecretJwt_iatInTheFuture() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(claimsSetWithIatInTheFuture()), false, true);
-    }
-
-    @Test
-    public void testInvalidSecretJwt_expInThePast() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(claimsSetWithExpInThePast()), false, true);
-    }
-    
-    @Test
-    public void testInvalidSecretJwt_withoutJit() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(claimsSetWithoutJit()), false, true);
-    }
-    
-    @Test
-    public void testInvalidSecretJwt_jitReplayDetected() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.CLIENT_SECRET_JWT,
-                createSecretJWT(validClaimsSet()), true, true);
-    }
-
-    @Test
-    public void testInvalidPrivateKeyJwt_iatInTheFuture() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(claimsSetWithIatInTheFuture()), false, true);
-    }
-
-    @Test
-    public void testInvalidPrivateKeyJwt_expInThePast() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(claimsSetWithExpInThePast()), false, true);
-    }
-    
-    @Test
-    public void testInvalidPrivateKeyJwt_withoutJit() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(claimsSetWithoutJit()), false, true);
-    }
-    
-    @Test
-    public void testInvalidPrivateKeyJwt_jitReplayDetected() throws Exception {
-        testFailingJwtAuth(ClientAuthenticationMethod.PRIVATE_KEY_JWT,
-                createPrivateKeyJWT(validClaimsSet()), true, true);
-    }
-    
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidatorTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidatorTest.java
deleted file mode 100644
index 62d60f89..00000000
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/OIDCClientInfoCredentialValidatorTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.login.LoginException;
-
-import net.shibboleth.idp.authn.AuthenticationResult;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.AuthenticationErrorContext;
-import net.shibboleth.idp.authn.context.UsernamePasswordContext;
-import net.shibboleth.idp.authn.impl.ValidateCredentials;
-import net.shibboleth.idp.authn.impl.testing.BaseAuthenticationContextTest;
-import net.shibboleth.idp.authn.principal.UsernamePrincipal;
-import net.shibboleth.idp.profile.testing.ActionTestingSupport;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.shared.codec.StringDigester;
-import net.shibboleth.shared.codec.StringDigester.OutputFormat;
-import net.shibboleth.shared.component.ComponentInitializationException;
-
-import org.springframework.webflow.execution.Event;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.oauth2.sdk.auth.Secret;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
-
-/** Unit test for {@link OIDCClientInfoCredentialValidator}. */
-public class OIDCClientInfoCredentialValidatorTest extends BaseAuthenticationContextTest {
-
-    private ClientID clientId;
-    private Secret clientSecret;
-    
-    private OIDCClientInfoCredentialValidator validator;
-    
-    private ValidateCredentials action;
-
-    @BeforeMethod public void setUp() throws ComponentInitializationException {
-        super.setUp();
-
-        clientId = new ClientID("mockId");
-        clientSecret = new Secret("secret1234567890secret1234567890secret1234567890");
-        
-        validator = new OIDCClientInfoCredentialValidator();
-        validator.setId("test");
-        validator.initialize();
-        
-        action = new ValidateCredentials();
-        action.setValidators(Collections.singletonList(validator));
-        
-        final Map<String,Collection<String>> mappings = new HashMap<>();
-        mappings.put("InvalidPassword", Collections.singleton(AuthnEventIds.INVALID_CREDENTIALS));
-        mappings.put(AuthnEventIds.UNKNOWN_USERNAME, Collections.singleton(AuthnEventIds.UNKNOWN_USERNAME));
-        action.setClassifiedMessages(mappings);
-
-        action.initialize();
-
-        final OIDCMetadataContext oidcContext = new OIDCMetadataContext();
-        final OIDCClientMetadata metadata = new OIDCClientMetadata();
-        final Secret secret = new Secret("secret1234567890secret1234567890secret1234567890");
-        final OIDCClientInformation clientInformation = 
-                new OIDCClientInformation(clientId, new Date(), metadata, secret);
-        oidcContext.setClientInformation(clientInformation);
-        prc.ensureInboundMessageContext().addSubcontext(oidcContext);
-    }
-
-    @Test public void testMissingFlow() {
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_AUTHN_CTX);
-    }
-
-    @Test public void testMissingUser() {
-        prc.ensureSubcontext(AuthenticationContext.class).setAttemptedFlow(authenticationFlows.get(0));
-        
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
-    }
-
-    @Test public void testMissingUser2() {
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        ac.setAttemptedFlow(authenticationFlows.get(0));
-        ac.ensureSubcontext(UsernamePasswordContext.class);
-
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
-    }
-
-    @Test public void testBadPassword() {
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        ac.setAttemptedFlow(authenticationFlows.get(0));
-        ac.ensureSubcontext(UsernamePasswordContext.class).setUsername(clientId.getValue()).setPassword("foo");
-
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertEvent(event, "InvalidPassword");
-        final AuthenticationErrorContext errorCtx = ac.ensureSubcontext(AuthenticationErrorContext.class);
-        Assert.assertTrue(errorCtx.getExceptions().get(0) instanceof LoginException);
-        Assert.assertFalse(errorCtx.isClassifiedError("UnknownUsername"));
-        Assert.assertTrue(errorCtx.isClassifiedError("InvalidPassword"));
-    }
-
-    @Test public void testAuthorized() {
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        ac.setAttemptedFlow(authenticationFlows.get(0));
-        ac.ensureSubcontext(UsernamePasswordContext.class).setUsername(clientId.getValue()).setPassword(clientSecret.getValue());
-
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-    
-    @Test public void testAuthorizedSHA2() throws NoSuchAlgorithmException {
-        final AuthenticationContext ac = prc.ensureSubcontext(AuthenticationContext.class);
-        ac.setAttemptedFlow(authenticationFlows.get(0));
-        ac.ensureSubcontext(UsernamePasswordContext.class).setUsername(clientId.getValue()).setPassword(clientSecret.getValue());
-
-        final OIDCClientMetadata metadata = new OIDCClientMetadata();
-        final Secret secret = new Secret("{SHA2}" + new StringDigester("SHA-256", OutputFormat.BASE64).apply(clientSecret.getValue()));
-        final OIDCClientInformation clientInformation = 
-                new OIDCClientInformation(clientId, new Date(), metadata, secret);
-        prc.ensureInboundMessageContext().ensureSubcontext(OIDCMetadataContext.class).setClientInformation(clientInformation);
-        
-        final Event event = action.execute(src);
-        ActionTestingSupport.assertProceedEvent(event);
-        
-        final AuthenticationResult ar = ac.getAuthenticationResult();
-        Assert.assertNotNull(ar);
-        assert ar != null;
-        Assert.assertEquals(ar.getSubject().getPrincipals(UsernamePrincipal.class).iterator()
-                .next().getName(), clientId.getValue());
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java
deleted file mode 100644
index e2c3c91c..00000000
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.authn.impl;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.Set;
-
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
-import com.nimbusds.oauth2.sdk.auth.ClientSecretPost;
-import com.nimbusds.oauth2.sdk.auth.Secret;
-import com.nimbusds.oauth2.sdk.id.ClientID;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
-
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.oidc.authn.context.OAuth2ClientAuthenticationContext;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
-import net.shibboleth.idp.profile.testing.ActionTestingSupport;
-import net.shibboleth.idp.profile.testing.RequestContextBuilder;
-
-/**
- * Unit tests for {@link ValidateClientAuthenticationType}.
- */
-public class ValidateClientAuthenticationTypeTest {
-    
-    private ClientID clientId;
-    private Secret clientSecret;
-    
-    private ValidateClientAuthenticationType action;
-    
-    private RequestContext rc;
-    private ProfileRequestContext prc;
-    
-    private Set<ClientAuthenticationMethod> enabledMethods;
-    
-    @BeforeMethod
-    public void init() throws ComponentInitializationException {
-        clientId = new ClientID("mockId");
-        clientSecret = new Secret("secret1234567890secret1234567890secret1234567890");
-        enabledMethods = Collections.emptySet();
-        
-        action = new ValidateClientAuthenticationType();
-        action.setTokenEndpointAuthMethodsLookupStrategy(p -> {
-            return enabledMethods;
-            }
-        );
-        action.initialize();
-    }
-    
-    protected void initializeRequestCtx(final ClientAuthenticationMethod method,
-            final ClientAuthenticationMethod storedMethod) throws JOSEException, ComponentInitializationException {
-        final ClientAuthentication clientAuth;
-        if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) {
-            clientAuth = new ClientSecretBasic(clientId, clientSecret);
-        } else if (method.equals(ClientAuthenticationMethod.CLIENT_SECRET_POST)) {
-            clientAuth = new ClientSecretPost(clientId, clientSecret);
-        } else {
-            clientAuth = null;
-        }
-        rc = new RequestContextBuilder().setInboundMessage(null).buildRequestContext();
-        prc = new WebflowRequestContextProfileRequestContextLookup().apply(rc);
-        prc.addSubcontext(new AuthenticationContext()).addSubcontext(
-                new OAuth2ClientAuthenticationContext().setClientAuthentication(clientAuth));
-        
-        final OIDCMetadataContext oidcContext = new OIDCMetadataContext();
-        final OIDCClientMetadata metadata = new OIDCClientMetadata();
-        metadata.setTokenEndpointAuthMethod(storedMethod);
-        // we're not actually validating the secret so it doesn't matter
-        final Secret secret = new Secret("WRONG1234567890secret1234567890secret1234567890");
-        final OIDCClientInformation clientInformation = 
-                new OIDCClientInformation(clientId, new Date(), metadata, secret);
-        oidcContext.setClientInformation(clientInformation);
-        prc.ensureInboundMessageContext().addSubcontext(oidcContext);
-    }
-
-    @Test
-    public void testNoAuthnContext() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
-                ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        prc.removeSubcontext(AuthenticationContext.class);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertEvent(e, AuthnEventIds.INVALID_AUTHN_CTX);
-    }
-    
-    @Test
-    public void testNoneDisabled() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.NONE,
-                ClientAuthenticationMethod.NONE);
-        prc.ensureSubcontext(AuthenticationContext.class).removeSubcontext(OAuth2ClientAuthenticationContext.class);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertEvent(e, EventIds.ACCESS_DENIED);
-    }
-
-    @Test
-    public void testNoneEnabled() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.NONE,
-                ClientAuthenticationMethod.NONE);
-        enabledMethods = Collections.singleton(ClientAuthenticationMethod.NONE);
-        prc.ensureSubcontext(AuthenticationContext.class).removeSubcontext(OAuth2ClientAuthenticationContext.class);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-    }
-    
-    @Test
-    public void testBasicDisabled() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.NONE,
-                ClientAuthenticationMethod.NONE);
-        enabledMethods = Collections.singleton(ClientAuthenticationMethod.CLIENT_SECRET_POST);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertEvent(e, EventIds.ACCESS_DENIED);
-    }
-    
-    @Test
-    public void testBasicEnabled() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
-                ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        enabledMethods = Collections.singleton(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-    }
-
-    @Test
-    public void testNoMetadata() throws Exception {
-        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
-                ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        prc.ensureInboundMessageContext().removeSubcontext(
-                prc.ensureInboundMessageContext().ensureSubcontext(OIDCMetadataContext.class));
-        enabledMethods = Collections.singleton(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-        final Event e = action.execute(rc);
-        ActionTestingSupport.assertProceedEvent(e);
-    }
-
-}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list