diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/MockOidcClientConfiguration.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/MockOidcClientConfiguration.java new file mode 100644 index 00000000000..b59d75a192f --- /dev/null +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/MockOidcClientConfiguration.java @@ -0,0 +1,167 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual 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.wildfly.security.http.oidc; + +import com.gargoylesoftware.htmlunit.TextPage; +import io.restassured.RestAssured; +import mockit.Mock; +import mockit.MockUp; +import mockit.integration.junit4.JMockit; +import okhttp3.mockwebserver.MockWebServer; +import org.apache.http.HttpStatus; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.security.http.HttpServerAuthenticationMechanism; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import static org.jose4j.jws.AlgorithmIdentifiers.HMAC_SHA256; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; +import static org.wildfly.security.http.oidc.KeycloakConfiguration.ALICE; +import static org.wildfly.security.http.oidc.KeycloakConfiguration.ALICE_PASSWORD; +import static org.wildfly.security.http.oidc.Oidc.AuthenticationRequestFormat.REQUEST; +import static org.wildfly.security.http.oidc.Oidc.AuthenticationRequestFormat.REQUEST_URI; +import static org.wildfly.security.http.oidc.Oidc.OIDC_NAME; +import static org.wildfly.security.http.oidc.Oidc.OIDC_SCOPE; + +/** + * Tests for cases where the OpenID provider does not support + * request parameters when sending the request object as a JWT. + * The OidcClientConfiguration class is mocked to return values + * indicating a lack of support for request parameters. + * + * @author Prarthona Paul + */ +@RunWith(JMockit.class) +public class MockOidcClientConfiguration extends OidcBaseTest { + + @BeforeClass + public static void startTestContainers() throws Exception { + assumeTrue("Docker isn't available, OIDC tests will be skipped", isDockerAvailable()); + KEYCLOAK_CONTAINER = new KeycloakContainer(); + KEYCLOAK_CONTAINER.start(); + sendRealmCreationRequest(KeycloakConfiguration.getRealmRepresentation(TEST_REALM, CLIENT_ID, CLIENT_SECRET, CLIENT_HOST_NAME, CLIENT_PORT, CLIENT_APP, false)); + client = new MockWebServer(); + client.start(CLIENT_PORT); + } + + @AfterClass + public static void generalCleanup() throws Exception { + if (KEYCLOAK_CONTAINER != null) { + RestAssured + .given() + .auth().oauth2(KeycloakConfiguration.getAdminAccessToken(KEYCLOAK_CONTAINER.getAuthServerUrl())) + .when() + .delete(KEYCLOAK_CONTAINER.getAuthServerUrl() + "/admin/realms/" + TEST_REALM).then().statusCode(204); + KEYCLOAK_CONTAINER.stop(); + } + if (client != null) { + client.shutdown(); + } + } + + @BeforeClass + public static void beforeClass() { + System.setProperty("oidc.provider.url", KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/" + TEST_REALM); + } + + @AfterClass + public static void afterClass() { + System.clearProperty("oidc.provider.url"); + } + + @Test + public void testOidcWithRequestParameterUnsupported() throws Exception { + mockOidcClientConfig(); + performAuthentication(getOidcConfigurationInputStreamWithRequestParameter(REQUEST.getValue()), REQUEST.getValue()); + } + + @Test + public void testOidcWithRequestUriParameterUnsupported() throws Exception { + mockOidcClientConfig(); + performAuthentication(getOidcConfigurationInputStreamWithRequestParameter(REQUEST_URI.getValue()), REQUEST_URI.getValue()); + } + + public void performAuthentication(InputStream oidcConfig, String requestFormat) throws Exception { + Map props = new HashMap<>(); + OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig); + assertEquals(OidcClientConfiguration.RelativeUrlsUsed.NEVER, oidcClientConfiguration.getRelativeUrls()); + OidcClientContext oidcClientContext = new OidcClientContext(oidcClientConfiguration); + oidcFactory = new OidcMechanismFactory(oidcClientContext); + HttpServerAuthenticationMechanism mechanism = oidcFactory.createAuthenticationMechanism(OIDC_NAME, props, getCallbackHandler()); + + URI requestUri = new URI(getClientUrl()); + TestingHttpServerRequest request = new TestingHttpServerRequest(null, requestUri); + mechanism.evaluateRequest(request); + TestingHttpServerResponse response = request.getResponse(); + assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusCode()); + assertEquals(Status.NO_AUTH, request.getResult()); + assertFalse(response.getFirstResponseHeaderValue("Location").contains(requestFormat + "=")); + assertTrue(response.getFirstResponseHeaderValue("Location").contains("scope=" + OIDC_SCOPE + "+phone+profile+email")); //ALL scopes should be added to the URL directly + + client.setDispatcher(createAppResponse(mechanism, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT)); + + TextPage page = loginToKeycloak(ALICE, ALICE_PASSWORD, requestUri, response.getLocation(), + response.getCookies()).click(); + assertTrue(page.getContent().contains(CLIENT_PAGE_TEXT)); + } + + + private void mockOidcClientConfig(){ + new MockUp(){ + // Used to indicate that the OpenID provider does not support request_uri parameter + @Mock + boolean getRequestUriParameterSupported(){ + return false; + } + + // Used to indicate that the OpenID provider does not support request parameter + @Mock + boolean getRequestParameterSupported(){ + return false; + } + }; + } + + private InputStream getOidcConfigurationInputStreamWithRequestParameter(String requestParameter){ + String oidcConfig = "{\n" + + " \"client-id\" : \"" + CLIENT_ID + "\",\n" + + " \"provider-url\" : \"" + KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/" + TEST_REALM + "/" + "\",\n" + + " \"public-client\" : \"false\",\n" + + " \"ssl-required\" : \"EXTERNAL\",\n" + + " \"authentication-request-format\" : \"" + requestParameter + "\",\n" + + " \"request-object-signing-algorithm\" : \"" + HMAC_SHA256 + "\",\n" + + " \"scope\" : \"profile email phone\",\n" + + " \"credentials\" : {\n" + + " \"secret\" : \"" + CLIENT_SECRET + "\"\n" + + " }\n" + + "}"; + return new ByteArrayInputStream(oidcConfig.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java index 7855dc22a65..0ba8e2713a1 100644 --- a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java @@ -137,11 +137,11 @@ private SecurityIdentity performConnectionTest(SSLContext serverContext, SSLCont SSLSocket sslSocket = (SSLSocket) clientContext.getSocketFactory().createSocket(InetAddress.getLoopbackAddress(), 1111); sslSocket.getSession(); + System.out.println("Client connected"); return sslSocket; } catch (Exception e) { + System.out.println("Client Connection Failed"); throw new RuntimeException(e); - } finally { - System.out.println("Client connected"); } }); diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java index 2ec81161b92..9d8cbe551ea 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java @@ -104,7 +104,7 @@ public class SSLAuthenticationTest { private final int TESTING_PORT = 18201; private static final char[] PASSWORD = "Elytron".toCharArray(); - private static final String JKS_LOCATION = "./target/test-classes/jks"; + private static final String JKS_LOCATION = "./target/test-classes/pkcs12"; private static final String CA_CRL_LOCATION = "./target/test-classes/ca/crl"; private static final String ICA_CRL_LOCATION = "./target/test-classes/ica/crl"; private static final File WORKING_DIR_CACRL = new File(CA_CRL_LOCATION); @@ -129,7 +129,7 @@ private static TrustManagerFactory getTrustManagerFactory() throws Exception { } private static KeyStore createKeyStore() throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(null, null); return ks; } diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java index 6fb2a57b055..392b291de8d 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java @@ -90,7 +90,7 @@ public class SSLv2HelloAuthenticationTest { private static final String CLIENT_CONFIG = "sslv2-hello-authentication-config.xml"; private static final char[] PASSWORD = "Elytron".toCharArray(); - private static final String CA_JKS_LOCATION = "./target/test-classes/ca/jks"; + private static final String CA_JKS_LOCATION = "./target/test-classes/ca/pkcs12"; private static File ladybirdFile = null; private static File scarabFile = null; private static File beetlesFile = null; @@ -120,7 +120,7 @@ public static void setUp() throws Exception{ createKeyStores(ladybirdFile, scarabFile, beetlesFile, trustFile); - securityRealm = new KeyStoreBackedSecurityRealm(loadKeyStore("/ca/jks/beetles.keystore")); + securityRealm = new KeyStoreBackedSecurityRealm(loadKeyStore("/ca/pkcs12/beetles.keystore")); securityDomain = SecurityDomain.builder() .addRealm("KeystoreRealm", securityRealm) @@ -163,7 +163,7 @@ public void testOneWaySSLv2HelloProtocolMatch() throws Exception { SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) - .setKeyManager(getKeyManager("/ca/jks/scarab.keystore")) + .setKeyManager(getKeyManager("/ca/pkcs12/scarab.keystore")) .setProtocolSelector(ProtocolSelector.empty().add(EnumSet.copyOf(list))) .build().create(); @@ -188,7 +188,7 @@ public void testTwoWaySSLv2HelloProtocolMatch() throws Exception { SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) - .setKeyManager(getKeyManager("/ca/jks/scarab.keystore")) + .setKeyManager(getKeyManager("/ca/pkcs12/scarab.keystore")) .setTrustManager(getCATrustManager()) .setNeedClientAuth(true) .setProtocolSelector(ProtocolSelector.empty().add(EnumSet.copyOf(list))) @@ -215,7 +215,7 @@ public void testTwoWaySSLv2HelloProtocolMatch() throws Exception { public void testTwoWaySSLv2HelloNotEnabled() throws Exception { SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) - .setKeyManager(getKeyManager("/ca/jks/scarab.keystore")) + .setKeyManager(getKeyManager("/ca/pkcs12/scarab.keystore")) .setTrustManager(getCATrustManager()) .setNeedClientAuth(true) .build().create(); @@ -244,7 +244,7 @@ public void testTwoWaySSLv2HelloNoClientSupport() throws Exception { SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) - .setKeyManager(getKeyManager("/ca/jks/scarab.keystore")) + .setKeyManager(getKeyManager("/ca/pkcs12/scarab.keystore")) .setTrustManager(getCATrustManager()) .setNeedClientAuth(true) .setProtocolSelector(ProtocolSelector.empty().add(EnumSet.copyOf(list))) @@ -274,7 +274,7 @@ public void testTwoWaySSlv2HelloNoServerSupport() throws Exception { SSLContext serverContext = new SSLContextBuilder() .setSecurityDomain(securityDomain) - .setKeyManager(getKeyManager("/ca/jks/scarab.keystore")) + .setKeyManager(getKeyManager("/ca/pkcs12/scarab.keystore")) .setTrustManager(getCATrustManager()) .setNeedClientAuth(true) .setProtocolSelector(ProtocolSelector.empty().add(EnumSet.copyOf(list))) @@ -377,7 +377,7 @@ private static X509ExtendedKeyManager getKeyManager(final String keystorePath) t */ private static X509TrustManager getCATrustManager() throws Exception { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); - trustManagerFactory.init(loadKeyStore("/ca/jks/ca.truststore")); + trustManagerFactory.init(loadKeyStore("/ca/pkcs12/ca.truststore")); for (TrustManager current : trustManagerFactory.getTrustManagers()) { if (current instanceof X509TrustManager) { @@ -389,13 +389,13 @@ private static X509TrustManager getCATrustManager() throws Exception { } private static KeyStore loadKeyStore() throws Exception{ - KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(null,null); return ks; } private static KeyStore loadKeyStore(final String path) throws Exception { - KeyStore keyStore = KeyStore.getInstance("jks"); + KeyStore keyStore = KeyStore.getInstance("PKCS12"); try (InputStream caTrustStoreFile = SSLAuthenticationTest.class.getResourceAsStream(path)) { keyStore.load(caTrustStoreFile, PASSWORD); } diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java index 0952a781560..826916e29ca 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java @@ -65,7 +65,7 @@ public class TLS13AuthenticationTest { private static final String CLIENT_CONFIG = "tls13-authentication-config.xml"; private static final char[] PASSWORD = "Elytron".toCharArray(); - private static final String CA_JKS_LOCATION = "./target/test-classes/jks"; + private static final String CA_JKS_LOCATION = "./target/test-classes/pkcs12"; private static CAGenerationTool caGenerationTool = null; private static SecurityDomain securityDomain = null; diff --git a/tests/base/src/test/resources/org/wildfly/security/auth/client/wildfly-masked-password-ssl-config-v1_4.xml b/tests/base/src/test/resources/org/wildfly/security/auth/client/wildfly-masked-password-ssl-config-v1_4.xml index d458d71f173..133acd78f2d 100644 --- a/tests/base/src/test/resources/org/wildfly/security/auth/client/wildfly-masked-password-ssl-config-v1_4.xml +++ b/tests/base/src/test/resources/org/wildfly/security/auth/client/wildfly-masked-password-ssl-config-v1_4.xml @@ -21,10 +21,11 @@ - + + - + diff --git a/tests/base/src/test/resources/org/wildfly/security/ssl/ocsp-responder.xml b/tests/base/src/test/resources/org/wildfly/security/ssl/ocsp-responder.xml index 50b99e567d7..8b0d7755811 100644 --- a/tests/base/src/test/resources/org/wildfly/security/ssl/ocsp-responder.xml +++ b/tests/base/src/test/resources/org/wildfly/security/ssl/ocsp-responder.xml @@ -19,7 +19,7 @@ JKS - password=Elytron,keystore=file:target/test-classes/jks/ocsp-responder.keystore + password=Elytron,keystore=file:target/test-classes/pkcs12/ocsp-responder.keystore SHA256withRSA diff --git a/tests/base/src/test/resources/org/wildfly/security/ssl/ssl-authentication-config.xml b/tests/base/src/test/resources/org/wildfly/security/ssl/ssl-authentication-config.xml index 5577e556fe2..2f5ab506492 100644 --- a/tests/base/src/test/resources/org/wildfly/security/ssl/ssl-authentication-config.xml +++ b/tests/base/src/test/resources/org/wildfly/security/ssl/ssl-authentication-config.xml @@ -22,41 +22,44 @@ - - + + + - - + + + - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/tests/base/src/test/resources/org/wildfly/security/ssl/sslv2-hello-authentication-config.xml b/tests/base/src/test/resources/org/wildfly/security/ssl/sslv2-hello-authentication-config.xml index 6269aefcace..c3ca9fc93d3 100644 --- a/tests/base/src/test/resources/org/wildfly/security/ssl/sslv2-hello-authentication-config.xml +++ b/tests/base/src/test/resources/org/wildfly/security/ssl/sslv2-hello-authentication-config.xml @@ -22,11 +22,12 @@ - - + + + - - + + diff --git a/tests/base/src/test/resources/org/wildfly/security/ssl/tls13-authentication-config.xml b/tests/base/src/test/resources/org/wildfly/security/ssl/tls13-authentication-config.xml index 84c57691b1c..e9146013afc 100644 --- a/tests/base/src/test/resources/org/wildfly/security/ssl/tls13-authentication-config.xml +++ b/tests/base/src/test/resources/org/wildfly/security/ssl/tls13-authentication-config.xml @@ -22,11 +22,12 @@ - - + + + - - + + diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java index 4481352b8f8..e28f884d999 100644 --- a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CAGenerationTool.java @@ -66,7 +66,7 @@ public class CAGenerationTool implements Closeable { private static final String BEETLES_STORE = "beetles.keystore"; private static final String KEY_ALGORITHM = "RSA"; - private static final String KEYSTORE_TYPE = "JKS"; // TODO Switch to PKCS#12 + private static final String KEYSTORE_TYPE = "PKCS12"; private static final int OCSP_PORT = 4854; static final char[] PASSWORD = "Elytron".toCharArray(); @@ -144,6 +144,10 @@ public KeyStore getBeetlesKeyStore() { return loadKeyStore(new File(workingDir, BEETLES_STORE)); } + public String getKeyStoreType() { + return KEYSTORE_TYPE; + } + /** * @deprecated Use {@link CommonIdentity#getCertificate()} instead. */ @@ -364,8 +368,12 @@ private static KeyStore createEmptyKeyStore() { } } + File getKeyStoreFile(Identity identity) { + return new File(workingDir, identity.getKeyStoreName()); + } + KeyStore loadKeyStore(final Identity identity) { - return loadKeyStore(new File(workingDir, identity.getKeyStoreName())); + return loadKeyStore(getKeyStoreFile(identity)); } static KeyStore loadKeyStore(final File location) { diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java index 2d8f3664015..ffd89fbdf0a 100644 --- a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CommonIdentity.java @@ -16,6 +16,7 @@ package org.wildfly.security.ssl.test.util; +import java.io.File; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -42,8 +43,14 @@ public X509Certificate getCertificate() { return certificate; } + public String getKeyStoreType() { + return caGenerationTool.getKeyStoreType(); + } + public abstract KeyStore loadKeyStore(); + public abstract File getKeyStoreFile(); + public X509ExtendedKeyManager createKeyManager() { caGenerationTool.assertNotClosed(); diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java index a1ce69a2b5e..f7f2100c53f 100644 --- a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/CustomIdentity.java @@ -34,4 +34,9 @@ public KeyStore loadKeyStore() { return CAGenerationTool.loadKeyStore(keyStoreFile); } + @Override + public File getKeyStoreFile() { + return keyStoreFile; + } + } diff --git a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java index 28595b8e112..0983b2e928d 100644 --- a/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java +++ b/tests/common/src/test/java/org/wildfly/security/ssl/test/util/DefinedIdentity.java @@ -16,6 +16,7 @@ package org.wildfly.security.ssl.test.util; +import java.io.File; import java.security.KeyStore; import java.security.cert.X509Certificate; @@ -38,4 +39,9 @@ public KeyStore loadKeyStore() { return caGenerationTool.loadKeyStore(identity); } + @Override + public File getKeyStoreFile() { + return caGenerationTool.getKeyStoreFile(identity); + } + }