parent
5c2a5fac31
commit
3e9c729f9e
17 changed files with 221 additions and 139 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
@ -299,7 +299,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
server: ['bcfips-nonapproved-pkcs12']
|
||||
tests: ['group1']
|
||||
tests: ['group1', 'group2']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
@ -339,6 +339,7 @@ jobs:
|
|||
PARAMS["bcfips-nonapproved-pkcs12"]="-Pauth-server-quarkus,auth-server-fips140-2"
|
||||
# Tests in the package "forms" and some keystore related tests
|
||||
TESTGROUP["group1"]="-Dtest=org.keycloak.testsuite.forms.**,ClientAuthSignedJWTTest,CredentialsTest,JavaKeystoreKeyProviderTest,ServerInfoTest,UserFederationLdapConnectionTest,LDAPUserLoginTest"
|
||||
TESTGROUP["group2"]="-Dtest=org.keycloak.testsuite.x509.**,MutualTLSClientTest,FAPI1Test,FAPICIBATest" # Tests for X.509 authentication with users and clients
|
||||
|
||||
./mvnw clean install -nsu -B ${PARAMS["${{ matrix.server }}"]} ${TESTGROUP["${{ matrix.tests }}"]} -f testsuite/integration-arquillian/tests/base/pom.xml | misc/log/trimmer.sh
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2022 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.authentication.x509;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.common.crypto.UserIdentityExtractor;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.common.util.StreamUtil;
|
||||
import org.keycloak.rule.CryptoInitRule;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/** This is not tested in keycloak-core. The subclasses should be created in the crypto modules to make sure it is tested with corresponding modules (bouncycastle VS bouncycastle-fips) */
|
||||
public abstract class CertificateIdentityExtractorTest {
|
||||
|
||||
@ClassRule
|
||||
public static CryptoInitRule cryptoInitRule = new CryptoInitRule();
|
||||
|
||||
@Test
|
||||
public void testExtractsCertInPemFormat() throws Exception {
|
||||
X509Certificate x509Certificate = getCertificate();
|
||||
|
||||
String certificatePem = PemUtils.encodeCertificate(x509Certificate);
|
||||
|
||||
//X509AuthenticatorConfigModel config = new X509AuthenticatorConfigModel();
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getCertificatePemIdentityExtractor();
|
||||
|
||||
String userIdentity = (String) extractor.extractUserIdentity(new X509Certificate[]{x509Certificate});
|
||||
|
||||
assertEquals(certificatePem, userIdentity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractsCertInSubjectDNFormat() throws Exception {
|
||||
X509Certificate x509Certificate = getCertificate();
|
||||
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getX500NameExtractor("CN", certs -> {
|
||||
return certs[0].getSubjectX500Principal();
|
||||
});
|
||||
String userIdentity = (String) extractor.extractUserIdentity(new X509Certificate[]{x509Certificate});
|
||||
assertEquals("Test User", userIdentity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testX509SubjectAltName_otherName() throws Exception {
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getSubjectAltNameExtractor(0);
|
||||
|
||||
X509Certificate cert = getCertificate();
|
||||
|
||||
Object upn = extractor.extractUserIdentity(new X509Certificate[] { cert});
|
||||
Assert.assertEquals("test-user@some-company-domain", upn);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testX509SubjectAltName_email() throws Exception {
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getSubjectAltNameExtractor(1);
|
||||
|
||||
X509Certificate cert = getCertificate();
|
||||
|
||||
Object upn = extractor.extractUserIdentity(new X509Certificate[] { cert});
|
||||
Assert.assertEquals("test@somecompany.com", upn);
|
||||
}
|
||||
|
||||
|
||||
private X509Certificate getCertificate() throws Exception {
|
||||
InputStream is = getClass().getResourceAsStream("/certs/UPN-cert.pem");
|
||||
|
||||
String s = StreamUtil.readString(is, Charset.defaultCharset());
|
||||
|
||||
return PemUtils.decodeCertificate(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2022 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.crypto.def.test;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.authentication.x509.CertificateIdentityExtractorTest;
|
||||
import org.keycloak.common.util.Environment;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class DefaultCertificateIdentityExtractorTest extends CertificateIdentityExtractorTest {
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
// Run this test just if java is not in FIPS mode
|
||||
Assume.assumeFalse("Java is in FIPS mode. Skipping the test.", Environment.isJavaInFipsMode());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2022 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.crypto.fips.test;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.authentication.x509.CertificateIdentityExtractorTest;
|
||||
import org.keycloak.common.util.Environment;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class FIPS1402CertificateIdentityExtractorTest extends CertificateIdentityExtractorTest {
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
// Run this test just if java is in FIPS mode
|
||||
Assume.assumeTrue("Java is not in FIPS mode. Skipping the test.", Environment.isJavaInFipsMode());
|
||||
}
|
||||
}
|
|
@ -126,6 +126,7 @@ mvn clean install -f common -DskipTests=true
|
|||
mvn clean install -f core -DskipTests=true
|
||||
mvn clean install -f server-spi -DskipTests=true
|
||||
mvn clean install -f server-spi-private -DskipTests=true
|
||||
mvn clean install -f services -DskipTests=true
|
||||
mvn clean install -f crypto/fips1402
|
||||
```
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -41,15 +40,18 @@ public class X509ClientAuthenticator extends AbstractClientAuthenticator {
|
|||
// These are not recognized by default in RFC1779 or RFC2253 and hence not read in the java by default
|
||||
private static final Map<String, String> CUSTOM_OIDS = new HashMap<>();
|
||||
private static final Map<String, String> CUSTOM_OIDS_REVERSED = new HashMap<>();
|
||||
|
||||
static {
|
||||
CUSTOM_OIDS.put("2.5.4.5", "serialNumber".toUpperCase());
|
||||
CUSTOM_OIDS.put("2.5.4.15", "businessCategory".toUpperCase());
|
||||
CUSTOM_OIDS.put("1.3.6.1.4.1.311.60.2.1.3", "jurisdictionCountryName".toUpperCase());
|
||||
CUSTOM_OIDS.put("1.2.840.113549.1.9.1", "emailAddress".toUpperCase());
|
||||
|
||||
// Reverse map
|
||||
for (Map.Entry<String, String> entry : CUSTOM_OIDS.entrySet()) {
|
||||
CUSTOM_OIDS_REVERSED.put(entry.getValue(), entry.getKey());
|
||||
}
|
||||
CUSTOM_OIDS_REVERSED.put("E", "1.2.840.113549.1.9.1"); // Another synonym for "EMAILADDRESS"
|
||||
}
|
||||
|
||||
protected static ServicesLogger logger = ServicesLogger.LOGGER;
|
||||
|
|
|
@ -149,7 +149,7 @@ public abstract class AbstractX509ClientCertificateAuthenticator implements Auth
|
|||
private static Function<X509Certificate[], String> getIssuerDNFunc(X509AuthenticatorConfigModel config) {
|
||||
return config.isCanonicalDnEnabled() ?
|
||||
certs -> certs[0].getIssuerX500Principal().getName(X500Principal.CANONICAL) :
|
||||
certs -> certs[0].getIssuerDN().getName();
|
||||
certs -> certs[0].getIssuerDN().toString();
|
||||
}
|
||||
|
||||
static UserIdentityExtractor fromConfig(X509AuthenticatorConfigModel config) {
|
||||
|
@ -168,7 +168,7 @@ public abstract class AbstractX509ClientCertificateAuthenticator implements Auth
|
|||
case SUBJECTDN:
|
||||
func = config.isCanonicalDnEnabled() ?
|
||||
certs -> certs[0].getSubjectX500Principal().getName(X500Principal.CANONICAL) :
|
||||
certs -> certs[0].getSubjectDN().getName();
|
||||
certs -> certs[0].getSubjectDN().toString();
|
||||
extractor = userIdExtractor.getPatternIdentityExtractor(pattern, func);
|
||||
break;
|
||||
case ISSUERDN:
|
||||
|
|
|
@ -67,12 +67,11 @@ import org.apache.http.client.methods.HttpGet;
|
|||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.connections.httpclient.HttpClientProvider;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.truststore.TruststoreProvider;
|
||||
import org.keycloak.utils.CRLUtils;
|
||||
|
@ -982,13 +981,11 @@ public class CertificateValidator {
|
|||
public GotOCSPFailOpen oCSPResponseCertificate(String responderCert) {
|
||||
if (responderCert != null && !responderCert.isEmpty()) {
|
||||
try {
|
||||
_responderCert = XMLSignatureUtil.getX509CertificateFromKeyInfoString(responderCert);
|
||||
_responderCert = PemUtils.decodeCertificate(responderCert);
|
||||
_responderCert.checkValidity();
|
||||
} catch(CertificateException e) {
|
||||
logger.warnf("Ignoring invalid certificate: %s", _responderCert);
|
||||
_responderCert = null;
|
||||
} catch (ProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return new GotOCSPFailOpen();
|
||||
|
|
|
@ -165,13 +165,11 @@ public class X509ClientCertificateAuthenticator extends AbstractX509ClientCertif
|
|||
|
||||
// Check whether to display the identity confirmation
|
||||
if (!config.getConfirmationPageDisallowed()) {
|
||||
// FIXME calling forceChallenge was the only way to display
|
||||
// Calling forceChallenge was the only way to display
|
||||
// a form to let users either choose the user identity from certificate
|
||||
// or to ignore it and proceed to a normal login screen. Attempting
|
||||
// to call the method "challenge" results in a wrong/unexpected behavior.
|
||||
// The question is whether calling "forceChallenge" here is ok from
|
||||
// the design viewpoint?
|
||||
context.forceChallenge(createSuccessResponse(context, certs[0].getSubjectDN().getName()));
|
||||
context.forceChallenge(createSuccessResponse(context, certs[0].getSubjectDN().toString()));
|
||||
// Do not set the flow status yet, we want to display a form to let users
|
||||
// choose whether to accept the identity from certificate or to specify username/password explicitly
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package org.keycloak.authentication.authenticators.x509;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.keycloak.rule.CryptoInitRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.common.crypto.UserIdentityExtractor;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.common.util.StreamUtil;
|
||||
|
||||
public class CertificatePemIdentityExtractorTest {
|
||||
|
||||
@ClassRule
|
||||
public static CryptoInitRule cryptoInitRule = new CryptoInitRule();
|
||||
|
||||
@Test
|
||||
public void testExtractsCertInPemFormat() throws Exception {
|
||||
InputStream is = getClass().getResourceAsStream("/certs/UPN-cert.pem");
|
||||
X509Certificate x509Certificate = PemUtils.decodeCertificate(StreamUtil.readString(is, Charset.defaultCharset()));
|
||||
String certificatePem = PemUtils.encodeCertificate(x509Certificate);
|
||||
|
||||
//X509AuthenticatorConfigModel config = new X509AuthenticatorConfigModel();
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getCertificatePemIdentityExtractor();
|
||||
|
||||
String userIdentity = (String) extractor.extractUserIdentity(new X509Certificate[]{x509Certificate});
|
||||
|
||||
assertEquals(certificatePem, userIdentity);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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 org.keycloak.authentication.authenticators.x509;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.cert.X509Certificate;
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.common.crypto.UserIdentityExtractor;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.common.util.StreamUtil;
|
||||
import org.keycloak.rule.CryptoInitRule;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class SubjectAltNameIdentityExtractorTest {
|
||||
|
||||
@ClassRule
|
||||
public static CryptoInitRule cryptoInitRule = new CryptoInitRule();
|
||||
|
||||
@Test
|
||||
public void testX509SubjectAltName_otherName() throws Exception {
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getSubjectAltNameExtractor(0);
|
||||
|
||||
X509Certificate cert = getCertificate();
|
||||
|
||||
Object upn = extractor.extractUserIdentity(new X509Certificate[] { cert});
|
||||
Assert.assertEquals("test-user@some-company-domain", upn);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testX509SubjectAltName_email() throws Exception {
|
||||
UserIdentityExtractor extractor = CryptoIntegration.getProvider().getIdentityExtractorProvider().getSubjectAltNameExtractor(1);
|
||||
|
||||
X509Certificate cert = getCertificate();
|
||||
|
||||
Object upn = extractor.extractUserIdentity(new X509Certificate[] { cert});
|
||||
Assert.assertEquals("test@somecompany.com", upn);
|
||||
}
|
||||
|
||||
|
||||
private X509Certificate getCertificate() throws Exception {
|
||||
InputStream is = getClass().getResourceAsStream("/certs/UPN-cert.pem");
|
||||
|
||||
String s = StreamUtil.readString(is, Charset.defaultCharset());
|
||||
|
||||
return PemUtils.decodeCertificate(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -81,16 +81,9 @@ Or slightly longer version (that allows you to specify debugging port as well as
|
|||
|
||||
and you will be able to attach remote debugger to the test. Unfortunately server and adapter are running in different JVMs, so this won't help to debug those.
|
||||
|
||||
### JBoss auth server debugging
|
||||
### Auth server debugging
|
||||
|
||||
When tests are run on JBoss based container (WildFly/EAP) there is possibility to attach a debugger, by default on localhost:5005.
|
||||
|
||||
The server won't wait to attach the debugger. There are some properties what can change the default behaviour.
|
||||
|
||||
-Dauth.server.debug.port=$PORT
|
||||
-Dauth.server.debug.suspend=y
|
||||
|
||||
More info: http://javahowto.blogspot.cz/2010/09/java-agentlibjdwp-for-attaching.html
|
||||
See below in the "Quarkus" section.
|
||||
|
||||
### JBoss app server debugging
|
||||
|
||||
|
@ -788,7 +781,14 @@ Run tests using the `auth-server-quarkus` profile:
|
|||
|
||||
Right now, the server runs in a separate process. To debug the server set `auth.server.debug` system property to `true`.
|
||||
|
||||
To configure the debugger port, set the `auth.server.debug.port` system property with any valid port number. Default is `5005`.
|
||||
To configure the debugger port, set the `auth.server.debug.port` system property with any valid port number. Default is `5005`.
|
||||
Note you can also set port for example to `*:5005` or `my-host:5005` to set the bind host.
|
||||
|
||||
By default, quarkus server is started in the testsuite and you need to attach remote debugger to it during running. You can
|
||||
use `auth.server.debug.suspend=y` to "suspend" server startup when running testsuite, which means that server startup is blocked
|
||||
until debugger is attached.
|
||||
|
||||
More info: http://javahowto.blogspot.cz/2010/09/java-agentlibjdwp-for-attaching.html
|
||||
|
||||
## Cookies testing
|
||||
In order to reproduce some specific cookies behaviour in browsers (like SameSite policies or 3rd party cookie blocking),
|
||||
|
|
|
@ -27,7 +27,9 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
@ -174,7 +176,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
|
|||
}
|
||||
|
||||
private Process startContainer() throws IOException {
|
||||
ProcessBuilder pb = new ProcessBuilder(getProcessCommands());
|
||||
ProcessBuilder pb = getProcessBuilder();
|
||||
File wrkDir = configuration.getProvidersPath().resolve("bin").toFile();
|
||||
ProcessBuilder builder = pb.directory(wrkDir).redirectErrorStream(true);
|
||||
|
||||
|
@ -199,8 +201,10 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
|
|||
return builder.start();
|
||||
}
|
||||
|
||||
private String[] getProcessCommands() {
|
||||
private ProcessBuilder getProcessBuilder() {
|
||||
List<String> commands = new ArrayList<>();
|
||||
Map<String, String> env = new HashMap<>();
|
||||
|
||||
commands.add(getCommand());
|
||||
commands.add("-v");
|
||||
commands.add("start");
|
||||
|
@ -209,10 +213,13 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
|
|||
|
||||
if (Boolean.parseBoolean(System.getProperty("auth.server.debug", "false"))) {
|
||||
commands.add("--debug");
|
||||
if (configuration.getDebugPort() > 0) {
|
||||
commands.add(Integer.toString(configuration.getDebugPort()));
|
||||
} else {
|
||||
commands.add(System.getProperty("auth.server.debug.port", "5005"));
|
||||
|
||||
String debugPort = configuration.getDebugPort() > 0 ? Integer.toString(configuration.getDebugPort()) : System.getProperty("auth.server.debug.port", "5005");
|
||||
env.put("DEBUG_PORT", debugPort);
|
||||
|
||||
String debugSuspend = System.getProperty("auth.server.debug.suspend");
|
||||
if (debugSuspend != null) {
|
||||
env.put("DEBUG_SUSPEND", debugSuspend);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +263,12 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
|
|||
|
||||
log.debugf("Quarkus parameters: %s", commands);
|
||||
|
||||
return commands.toArray(new String[0]);
|
||||
String[] processCommands = commands.toArray(new String[0]);
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(processCommands);
|
||||
pb.environment().putAll(env);
|
||||
|
||||
return pb;
|
||||
}
|
||||
|
||||
private void addStorageOptions(StoreProvider storeProvider, List<String> commands) {
|
||||
|
|
|
@ -616,6 +616,7 @@ public class FAPI1Test extends AbstractClientPoliciesTest {
|
|||
OIDCAdvancedConfigWrapper clientConfig = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep);
|
||||
clientConfig.setRequestUris(Collections.singletonList(TestApplicationResourceUrls.clientRequestUri()));
|
||||
clientConfig.setTlsClientAuthSubjectDn("EMAILADDRESS=contact@keycloak.org, CN=Keycloak Intermediate CA, OU=Keycloak, O=Red Hat, ST=MA, C=US");
|
||||
clientConfig.setAllowRegexPatternComparison(false);
|
||||
});
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(clientUUID);
|
||||
ClientRepresentation client = clientResource.toRepresentation();
|
||||
|
|
|
@ -370,6 +370,7 @@ public class FAPICIBATest extends AbstractClientPoliciesTest {
|
|||
OIDCAdvancedConfigWrapper clientConfig = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep);
|
||||
clientConfig.setRequestUris(Collections.singletonList(TestApplicationResourceUrls.clientRequestUri()));
|
||||
clientConfig.setTlsClientAuthSubjectDn("EMAILADDRESS=contact@keycloak.org, CN=Keycloak Intermediate CA, OU=Keycloak, O=Red Hat, ST=MA, C=US");
|
||||
clientConfig.setAllowRegexPatternComparison(false);
|
||||
setClientAuthMethodNeutralSettings(clientRep);
|
||||
});
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(clientUUID);
|
||||
|
@ -413,6 +414,7 @@ public class FAPICIBATest extends AbstractClientPoliciesTest {
|
|||
OIDCAdvancedConfigWrapper clientConfig = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep);
|
||||
clientConfig.setRequestUris(Collections.singletonList(TestApplicationResourceUrls.clientRequestUri()));
|
||||
clientConfig.setTlsClientAuthSubjectDn("EMAILADDRESS=contact@keycloak.org, CN=Keycloak Intermediate CA, OU=Keycloak, O=Red Hat, ST=MA, C=US");
|
||||
clientConfig.setAllowRegexPatternComparison(false);
|
||||
setClientAuthMethodNeutralSettings(clientRep);
|
||||
});
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(clientUUID);
|
||||
|
@ -442,6 +444,7 @@ public class FAPICIBATest extends AbstractClientPoliciesTest {
|
|||
OIDCAdvancedConfigWrapper clientConfig = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep);
|
||||
clientConfig.setRequestUris(Collections.singletonList(TestApplicationResourceUrls.clientRequestUri()));
|
||||
clientConfig.setTlsClientAuthSubjectDn("EMAILADDRESS=contact@keycloak.org, CN=Keycloak Intermediate CA, OU=Keycloak, O=Red Hat, ST=MA, C=US");
|
||||
clientConfig.setAllowRegexPatternComparison(false);
|
||||
setClientAuthMethodNeutralSettings(clientRep);
|
||||
});
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(clientUUID);
|
||||
|
|
|
@ -67,12 +67,16 @@ public class MutualTLSClientTest extends AbstractTestRealmKeycloakTest {
|
|||
exactSubjectDNConfiguration.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
exactSubjectDNConfiguration.setRedirectUris(Arrays.asList("https://localhost:8543/auth/realms/master/app/auth"));
|
||||
exactSubjectDNConfiguration.setClientAuthenticatorType(X509ClientAuthenticator.PROVIDER_ID);
|
||||
exactSubjectDNConfiguration.setAttributes(Collections.singletonMap(X509ClientAuthenticator.ATTR_SUBJECT_DN, EXACT_CERTIFICATE_SUBJECT_DN));
|
||||
Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put(X509ClientAuthenticator.ATTR_SUBJECT_DN, EXACT_CERTIFICATE_SUBJECT_DN);
|
||||
attrs.put(X509ClientAuthenticator.ATTR_ALLOW_REGEX_PATTERN_COMPARISON, "false");
|
||||
exactSubjectDNConfiguration.setAttributes(attrs);
|
||||
|
||||
ClientRepresentation obbSubjectDNConfiguration = KeycloakModelUtils.createClient(testRealm, OBB_SUBJECT_DN_CLIENT_ID);
|
||||
obbSubjectDNConfiguration.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
obbSubjectDNConfiguration.setRedirectUris(Arrays.asList("https://localhost:8543/auth/realms/master/app/auth"));
|
||||
obbSubjectDNConfiguration.setClientAuthenticatorType(X509ClientAuthenticator.PROVIDER_ID);
|
||||
obbSubjectDNConfiguration.setAttributes(Collections.singletonMap(X509ClientAuthenticator.ATTR_ALLOW_REGEX_PATTERN_COMPARISON, "false"));
|
||||
// ATTR_SUBJECT_DN will be set in the individual tests based on the requested Subject DN Format
|
||||
}
|
||||
|
||||
|
@ -193,7 +197,6 @@ public class MutualTLSClientTest extends AbstractTestRealmKeycloakTest {
|
|||
ClientResource client = ApiUtil.findClientByClientId(testRealm(), OBB_SUBJECT_DN_CLIENT_ID);
|
||||
ClientRepresentation clientRep = client.toRepresentation();
|
||||
OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep);
|
||||
config.setAllowRegexPatternComparison(false);
|
||||
config.setTlsClientAuthSubjectDn(expectedSubjectDN);
|
||||
client.update(clientRep);
|
||||
|
||||
|
|
Loading…
Reference in a new issue