This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new 413d75ec1d9 Enforce TLS client certificate and store the application
certificates for dynamic registration (#3316)
413d75ec1d9 is described below
commit 413d75ec1d9bd1b6a2b50e72bf4e7f0e53258218
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Mon Jul 20 09:11:06 2026 +0100
Enforce TLS client certificate and store the application certificates for
dynamic registration (#3316)
---
.../oauth2/services/AbstractTokenService.java | 37 ++++----
.../services/DynamicRegistrationService.java | 59 ++++++++++++
.../oauth2/services/AbstractTokenServiceTest.java | 90 ++++++++++++++++++
.../services/DynamicRegistrationServiceTest.java | 102 +++++++++++++++++++++
.../cxf/systest/jaxrs/security/oidc/client.xml | 3 +
.../jaxrs/security/oidc/oidc-server-dynreg.xml | 2 +-
6 files changed, 275 insertions(+), 18 deletions(-)
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java
index 78c844d360a..b753a9ed990 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java
@@ -161,26 +161,29 @@ public class AbstractTokenService extends
AbstractOAuthService {
}
protected void checkCertificateBinding(Client client, TLSSessionInfo
tlsSessionInfo) {
- String subjectDn =
client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN);
- if (subjectDn == null &&
client.getApplicationCertificates().isEmpty()) {
- LOG.warning("Client \"" + client.getClientId() + "\" can not be
bound to the TLS certificate");
- reportInvalidClient();
- }
X509Certificate cert =
OAuthUtils.getRootTLSCertificate(tlsSessionInfo);
-
- if (subjectDn != null
- &&
!subjectDn.equals(OAuthUtils.getSubjectDnFromTLSCertificates(cert))) {
- LOG.warning("Client \"" + client.getClientId() + "\" can not be
bound to the TLS certificate");
- reportInvalidClient();
- }
- String issuerDn =
client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_ISSUER_DN);
- if (issuerDn != null
- &&
!issuerDn.equals(OAuthUtils.getIssuerDnFromTLSCertificates(cert))) {
- LOG.warning("Client \"" + client.getClientId() + "\" can not be
bound to the TLS certificate");
- reportInvalidClient();
- }
if (!client.getApplicationCertificates().isEmpty()) {
compareTlsCertificates(tlsSessionInfo,
client.getApplicationCertificates());
+ } else {
+ String subjectDn =
client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN);
+ String issuerDn =
client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_ISSUER_DN);
+ if (subjectDn == null && issuerDn == null) {
+ LOG.warning("Client \"" + client.getClientId()
+ + "\" can not be bound to the TLS certificate");
+ reportInvalidClient();
+ }
+ if (subjectDn != null
+ &&
!subjectDn.equals(OAuthUtils.getSubjectDnFromTLSCertificates(cert))) {
+ LOG.warning("Client \"" + client.getClientId()
+ + "\" can not be bound to the TLS certificate");
+ reportInvalidClient();
+ }
+ if (issuerDn != null
+ &&
!issuerDn.equals(OAuthUtils.getIssuerDnFromTLSCertificates(cert))) {
+ LOG.warning("Client \"" + client.getClientId()
+ + "\" can not be bound to the TLS certificate");
+ reportInvalidClient();
+ }
}
OAuthUtils.setCertificateThumbprintConfirmation(getMessageContext(),
cert);
}
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
index eb0e387a744..8be6b6d9bda 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
@@ -18,10 +18,13 @@
*/
package org.apache.cxf.rs.security.oauth2.services;
+import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import javax.security.auth.x500.X500Principal;
+
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
@@ -38,6 +41,7 @@ import jakarta.ws.rs.core.Response.ResponseBuilder;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.UriBuilder;
import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.utils.ExceptionUtils;
@@ -51,6 +55,7 @@ import
org.apache.cxf.rs.security.oauth2.utils.AuthorizationUtils;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
import org.apache.cxf.rt.security.crypto.CryptoUtils;
+import org.apache.cxf.security.transport.TLSSessionInfo;
@Path("register")
public class DynamicRegistrationService {
@@ -62,6 +67,7 @@ public class DynamicRegistrationService {
private int clientIdSizeInBytes = DEFAULT_CLIENT_ID_SIZE;
private MessageContext mc;
private boolean supportRegistrationAccessTokens = true;
+ private boolean enforceTlsClientAuthCertificateBinding = true;
private String userRole;
private List<String> allowedClientScopes;
@@ -274,6 +280,8 @@ public class DynamicRegistrationService {
newClient.setTokenEndpointAuthMethod(tokenEndpointAuthMethod);
if
(OAuthConstants.TOKEN_ENDPOINT_AUTH_TLS.equals(tokenEndpointAuthMethod)) {
+ X509Certificate cert = enforceTlsClientAuthCertificateBinding
+ ? validateTlsClientAuthCertificateBinding(request) :
getTlsClientCertificate();
String subjectDn =
(String)request.getProperty(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN);
if (subjectDn != null) {
newClient.getProperties().put(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
subjectDn);
@@ -282,6 +290,15 @@ public class DynamicRegistrationService {
if (issuerDn != null) {
newClient.getProperties().put(OAuthConstants.TLS_CLIENT_AUTH_ISSUER_DN,
issuerDn);
}
+ if (cert != null) {
+ try {
+
newClient.getApplicationCertificates().add(Base64Utility.encode(cert.getEncoded()));
+ } catch (Exception ex) {
+ OAuthError error =
+ new OAuthError(INVALID_CLIENT_METADATA, "Unable to
register TLS client certificate");
+ reportInvalidRequestError(error);
+ }
+ }
}
// Client Registration Time
newClient.setRegisteredAt(System.currentTimeMillis() / 1000L);
@@ -298,6 +315,44 @@ public class DynamicRegistrationService {
return newClient;
}
+ protected X509Certificate getTlsClientCertificate() {
+ TLSSessionInfo tlsSessionInfo =
(TLSSessionInfo)mc.get(TLSSessionInfo.class.getName());
+ return tlsSessionInfo == null ? null :
OAuthUtils.getRootTLSCertificate(tlsSessionInfo);
+ }
+
+ protected X509Certificate
validateTlsClientAuthCertificateBinding(ClientRegistration request) {
+ X509Certificate cert = getTlsClientCertificate();
+ if (cert == null) {
+ OAuthError error =
+ new OAuthError(INVALID_CLIENT_METADATA, "TLS client
certificate is required");
+ reportInvalidRequestError(error);
+ }
+
+ String subjectDn =
(String)request.getProperty(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN);
+ if (subjectDn != null
+ && !isSameDistinguishedName(subjectDn,
OAuthUtils.getSubjectDnFromTLSCertificates(cert))) {
+ OAuthError error =
+ new OAuthError(INVALID_CLIENT_METADATA, "Invalid
tls_client_auth_subject_dn metadata");
+ reportInvalidRequestError(error);
+ }
+ String issuerDn =
(String)request.getProperty(OAuthConstants.TLS_CLIENT_AUTH_ISSUER_DN);
+ if (issuerDn != null
+ && !isSameDistinguishedName(issuerDn,
OAuthUtils.getIssuerDnFromTLSCertificates(cert))) {
+ OAuthError error =
+ new OAuthError(INVALID_CLIENT_METADATA, "Invalid
tls_client_auth_root_dn metadata");
+ reportInvalidRequestError(error);
+ }
+ return cert;
+ }
+
+ private boolean isSameDistinguishedName(String expectedDn, String
actualDn) {
+ try {
+ return new X500Principal(expectedDn).equals(new
X500Principal(actualDn));
+ } catch (IllegalArgumentException ex) {
+ return false;
+ }
+ }
+
protected void fromClientRegistrationToClient(ClientRegistration request,
Client client) {
final List<String> grantTypes = client.getAllowedGrantTypes();
@@ -419,6 +474,10 @@ public class DynamicRegistrationService {
this.supportRegistrationAccessTokens = supportRegistrationAccessTokens;
}
+ public void setEnforceTlsClientAuthCertificateBinding(boolean
enforceTlsClientAuthCertificateBinding) {
+ this.enforceTlsClientAuthCertificateBinding =
enforceTlsClientAuthCertificateBinding;
+ }
+
public void setUserRole(String userRole) {
this.userRole = userRole;
}
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenServiceTest.java
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenServiceTest.java
index 4e56b366987..91bba44fb2b 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenServiceTest.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenServiceTest.java
@@ -18,12 +18,21 @@
*/
package org.apache.cxf.rs.security.oauth2.services;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.SecurityContext;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.rs.security.oauth2.common.Client;
import org.apache.cxf.rs.security.oauth2.common.OAuthError;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.security.transport.TLSSessionInfo;
import org.junit.Test;
@@ -31,6 +40,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class AbstractTokenServiceTest {
@@ -79,6 +90,76 @@ public class AbstractTokenServiceTest {
assertSame(expected, actual);
}
+ @Test
+ public void testCheckCertificateBindingAcceptsDnOnlyClient() {
+ TestTokenService service = new TestTokenService();
+ Client client = new Client("c1", null, true);
+ client.getProperties().put(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
"CN=peer,O=Test,C=US");
+
+ service.callCheckCertificateBinding(client,
+ makeTlsSession("CN=peer,O=Test,C=US", "CN=issuer,O=Test,C=US"));
+ }
+
+ @Test
+ public void testCheckCertificateBindingRejectsDnOnlyClientMismatch() {
+ TestTokenService service = new TestTokenService();
+ Client client = new Client("c1", null, true);
+ client.getProperties().put(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
"CN=peer,O=Test,C=US");
+
+ InvalidClientException ex = assertThrows(InvalidClientException.class,
+ () -> service.callCheckCertificateBinding(client,
+ makeTlsSession("CN=other,O=Test,C=US",
"CN=issuer,O=Test,C=US")));
+
+ assertNotNull(ex.getError());
+ assertEquals(OAuthConstants.INVALID_CLIENT, ex.getError().getError());
+ }
+
+ @Test
+ public void testCheckCertificateBindingRejectsCertificateMismatch() {
+ TestTokenService service = new TestTokenService();
+ Client client = new Client("c2", null, true);
+ client.getApplicationCertificates().add(Base64Utility.encode(new
byte[] {9, 9, 9}));
+
+ InvalidClientException ex = assertThrows(InvalidClientException.class,
+ () -> service.callCheckCertificateBinding(client,
+ makeTlsSession("CN=peer,O=Test,C=US",
"CN=issuer,O=Test,C=US")));
+
+ assertNotNull(ex.getError());
+ assertEquals(OAuthConstants.INVALID_CLIENT, ex.getError().getError());
+ }
+
+ @Test
+ public void testCheckCertificateBindingAcceptsCertificateMatch() throws
Exception {
+ TestTokenService service = new TestTokenService();
+ X509Certificate cert = createCertificate("CN=peer,O=Test,C=US",
"CN=issuer,O=Test,C=US");
+
+ Client client = new Client("c3", null, true);
+
client.getApplicationCertificates().add(Base64Utility.encode(cert.getEncoded()));
+
+ service.callCheckCertificateBinding(client, makeTlsSession(cert));
+ }
+
+ private static TLSSessionInfo makeTlsSession(String subjectDn, String
issuerDn) {
+ X509Certificate cert = createCertificate(subjectDn, issuerDn);
+ return makeTlsSession(cert);
+ }
+
+ private static TLSSessionInfo makeTlsSession(X509Certificate cert) {
+ return new TLSSessionInfo("TLS_FAKE", null, new Certificate[] {cert});
+ }
+
+ private static X509Certificate createCertificate(String subjectDn, String
issuerDn) {
+ X509Certificate cert = mock(X509Certificate.class);
+ when(cert.getSubjectX500Principal()).thenReturn(new
X500Principal(subjectDn));
+ when(cert.getIssuerX500Principal()).thenReturn(new
X500Principal(issuerDn));
+ try {
+ when(cert.getEncoded()).thenReturn(new byte[] {1, 2, 3});
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ return cert;
+ }
+
private static final class TestTokenService extends AbstractTokenService {
private Client client;
private OAuthServiceException exception;
@@ -87,6 +168,15 @@ public class AbstractTokenServiceTest {
return getClient(clientId, clientSecret, params);
}
+ void callCheckCertificateBinding(Client boundClient, TLSSessionInfo
tlsSessionInfo) {
+ MessageContext mc = mock(MessageContext.class);
+ SecurityContext sc = mock(SecurityContext.class);
+ when(sc.getAuthenticationScheme()).thenReturn("");
+ when(mc.getSecurityContext()).thenReturn(sc);
+ setMessageContext(mc);
+ checkCertificateBinding(boundClient, tlsSessionInfo);
+ }
+
void setClient(Client client) {
this.client = client;
}
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
index 72fddf6516a..fa339c5b11c 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
@@ -18,19 +18,28 @@
*/
package org.apache.cxf.rs.security.oauth2.services;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
+import javax.security.auth.x500.X500Principal;
+
import jakarta.ws.rs.BadRequestException;
+import jakarta.ws.rs.core.SecurityContext;
+import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.rs.security.oauth2.common.Client;
import org.apache.cxf.rs.security.oauth2.common.OAuthError;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.security.transport.TLSSessionInfo;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class DynamicRegistrationServiceTest {
@@ -80,6 +89,95 @@ public class DynamicRegistrationServiceTest {
assertEquals(Collections.singletonList("openid"),
client.getRegisteredScopes());
}
+ @Test
+ public void testRejectsTlsClientAuthWithoutTlsCertificate() {
+ TestDynamicRegistrationService service = new
TestDynamicRegistrationService();
+ service.setEnforceTlsClientAuthCertificateBinding(true);
+ service.setMessageContext(createMessageContext("", null));
+
+ ClientRegistration request = new ClientRegistration();
+
request.setGrantTypes(Collections.singletonList(OAuthConstants.CLIENT_CREDENTIALS_GRANT));
+
request.setTokenEndpointAuthMethod(OAuthConstants.TOKEN_ENDPOINT_AUTH_TLS);
+ request.setProperty(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
+ "CN=client,OU=Test,O=Apache,C=US");
+
+ BadRequestException ex = assertThrows(BadRequestException.class,
+ () -> service.createClient(request));
+
+ assertInvalidClientMetadata(ex);
+ }
+
+ @Test
+ public void testRejectsTlsClientAuthWhenSubjectDnDoesNotMatchCertificate()
{
+ TestDynamicRegistrationService service = new
TestDynamicRegistrationService();
+ service.setEnforceTlsClientAuthCertificateBinding(true);
+ X509Certificate cert = createCertificate(
+ "CN=actual,OU=Test,O=Apache,C=US",
+ "CN=issuer,OU=Test,O=Apache,C=US");
+ service.setMessageContext(createMessageContext("", cert));
+
+ ClientRegistration request = new ClientRegistration();
+
request.setGrantTypes(Collections.singletonList(OAuthConstants.CLIENT_CREDENTIALS_GRANT));
+
request.setTokenEndpointAuthMethod(OAuthConstants.TOKEN_ENDPOINT_AUTH_TLS);
+ request.setProperty(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
+ "CN=expected,OU=Test,O=Apache,C=US");
+
+ BadRequestException ex = assertThrows(BadRequestException.class,
+ () -> service.createClient(request));
+
+ assertInvalidClientMetadata(ex);
+ }
+
+ @Test
+ public void testAcceptsTlsClientAuthWhenSubjectDnMatchesCertificate() {
+ TestDynamicRegistrationService service = new
TestDynamicRegistrationService();
+ service.setEnforceTlsClientAuthCertificateBinding(true);
+ String subjectDn = "CN=client,OU=Test,O=Apache,C=US";
+ X509Certificate cert = createCertificate(subjectDn,
"CN=issuer,OU=Test,O=Apache,C=US");
+ service.setMessageContext(createMessageContext("", cert));
+
+ ClientRegistration request = new ClientRegistration();
+
request.setGrantTypes(Collections.singletonList(OAuthConstants.CLIENT_CREDENTIALS_GRANT));
+
request.setTokenEndpointAuthMethod(OAuthConstants.TOKEN_ENDPOINT_AUTH_TLS);
+ request.setProperty(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN,
subjectDn);
+
+ Client client = service.createClient(request);
+ assertEquals(subjectDn,
client.getProperties().get(OAuthConstants.TLS_CLIENT_AUTH_SUBJECT_DN));
+ assertEquals(1, client.getApplicationCertificates().size());
+ }
+
+ private static void assertInvalidClientMetadata(BadRequestException ex) {
+ assertNotNull(ex.getResponse());
+ OAuthError error = (OAuthError)ex.getResponse().getEntity();
+ assertNotNull(error);
+ assertEquals("invalid_client_metadata", error.getError());
+ }
+
+ private static MessageContext createMessageContext(String authScheme,
X509Certificate cert) {
+ SecurityContext sc = mock(SecurityContext.class);
+ when(sc.getAuthenticationScheme()).thenReturn(authScheme);
+
+ MessageContext mc = mock(MessageContext.class);
+ when(mc.getSecurityContext()).thenReturn(sc);
+ if (cert != null) {
+ TLSSessionInfo tlsInfo = new TLSSessionInfo("TLS_FAKE", null, new
Certificate[] {cert});
+ when(mc.get(TLSSessionInfo.class.getName())).thenReturn(tlsInfo);
+ }
+ return mc;
+ }
+
+ private static X509Certificate createCertificate(String subjectDn, String
issuerDn) {
+ X509Certificate cert = mock(X509Certificate.class);
+ when(cert.getSubjectX500Principal()).thenReturn(new
X500Principal(subjectDn));
+ when(cert.getIssuerX500Principal()).thenReturn(new
X500Principal(issuerDn));
+ try {
+ when(cert.getEncoded()).thenReturn(new byte[] {1, 2, 3});
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ return cert;
+ }
+
private static Client createClient() {
Client client = new Client("client", "secret", true);
client.setAllowedGrantTypes(Collections.singletonList(OAuthConstants.CLIENT_CREDENTIALS_GRANT));
@@ -90,5 +188,9 @@ public class DynamicRegistrationServiceTest {
void applyClientRegistration(ClientRegistration request, Client
client) {
fromClientRegistrationToClient(request, client);
}
+
+ Client createClient(ClientRegistration request) {
+ return createNewClient(request);
+ }
}
}
diff --git
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/client.xml
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/client.xml
index 18a02bae892..be3d0239c0e 100644
---
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/client.xml
+++
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/client.xml
@@ -36,6 +36,9 @@
<http:conduit name="https://localhost.*">
<http:client ConnectionTimeout="3000000" ReceiveTimeout="3000000"/>
<http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="JKS" password="password"
resource="keys/Morpit.jks"/>
+ </sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="password"
resource="keys/Truststore.jks"/>
</sec:trustManagers>
diff --git
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-dynreg.xml
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-dynreg.xml
index 86d1b34970c..20e4d2954bb 100644
---
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-dynreg.xml
+++
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-dynreg.xml
@@ -56,7 +56,7 @@ under the License.
<sec:trustManagers>
<sec:keyStore type="JKS" password="password"
resource="keys/Truststore.jks"/>
</sec:trustManagers>
- <sec:clientAuthentication want="false" required="false"/>
+ <sec:clientAuthentication want="true" required="false"/>
</httpj:tlsServerParameters>
<httpj:sessionSupport>true</httpj:sessionSupport>
</httpj:engine>