[KEYCLOAK-6116] - Tests for X509 Subject Alternative Name Extension

This commit is contained in:
pedroigor 2018-02-20 17:50:10 -03:00
parent c5c285abc3
commit 6aee573e2e
7 changed files with 164 additions and 5 deletions

View file

@ -245,6 +245,13 @@
<include>empty.crl</include>
</includes>
</resource>
<resource>
<directory>${common.resources}/pki/root/ca</directory>
<includes>
<include>certs/clients/test-user-san-email@localhost.cert.pem</include>
<include>certs/clients/test-user@localhost.key.pem</include>
</includes>
</resource>
</resources>
</configuration>
</execution>

View file

@ -17,7 +17,10 @@
package org.keycloak.testsuite.drone;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor;
@ -25,9 +28,11 @@ import org.jboss.arquillian.drone.spi.Configurator;
import org.jboss.arquillian.drone.spi.DronePoint;
import org.jboss.arquillian.drone.webdriver.configuration.WebDriverConfiguration;
import org.jboss.arquillian.drone.webdriver.factory.BrowserCapabilitiesList;
import org.jboss.arquillian.drone.webdriver.factory.BrowserCapabilitiesList.PhantomJS;
import org.jboss.arquillian.drone.webdriver.factory.WebDriverFactory;
import org.jboss.logging.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -47,11 +52,36 @@ public class KeycloakWebDriverConfigurator extends WebDriverFactory implements C
if (webDriverCfg.getBrowser().equals("htmlUnit")) {
updateCapabilities(webDriverCfg);
} else if (webDriverCfg.getBrowser().equals("phantomjs")) {
configurePhantomJSDriver(webDriverCfg);
}
return webDriverCfg;
}
private void configurePhantomJSDriver(WebDriverConfiguration webDriverCfg) {
webDriverCfg.setBrowserInternal(new PhantomJS() {
@Override
public Map<String, ?> getRawCapabilities() {
List<String> cliArgs = new ArrayList<>();
String cliArgsProperty = System.getProperty("keycloak.phantomjs.cli.args");
if (cliArgsProperty != null) {
cliArgs = Arrays.asList(cliArgsProperty.split(" "));
} else {
cliArgs.add("--ignore-ssl-errors=true");
cliArgs.add("--web-security=false");
}
Map<String, Object> mergedCapabilities = new HashMap<>(super.getRawCapabilities());
mergedCapabilities.put(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgs.toArray(new String[cliArgs.size()]));
return mergedCapabilities;
}
});
}
// This is to ensure that default value of capabilities like "version" will be used just for the HtmlUnitDriver, but not for other drivers.
// Hence in configs we have "htmlUnit.version" instead of "version"

View file

@ -21,6 +21,7 @@ package org.keycloak.testsuite.x509;
import org.jboss.logging.Logger;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.keycloak.admin.client.resource.AuthenticationManagementResource;
import org.keycloak.authentication.AuthenticationFlow;
@ -57,6 +58,7 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.IdentityMapperType.USER_ATTRIBUTE;
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.ISSUERDN;
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.ISSUERDN_CN;
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.SUBJECTALTNAME_EMAIL;
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.SUBJECTDN_CN;
import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.SUBJECTDN_EMAIL;
@ -100,6 +102,27 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe
return true;
}
@BeforeClass
public static void onBeforeTestClass() {
if (System.getProperty("auth.server.container", "undefined").endsWith("wildfly")) {
String authServerHome = System.getProperty("auth.server.home");
if (authServerHome != null && System.getProperty("auth.server.ssl.required") != null) {
authServerHome = authServerHome + "/standalone/configuration";
StringBuilder cliArgs = new StringBuilder();
cliArgs.append("--ignore-ssl-errors=true ");
cliArgs.append("--web-security=false ");
cliArgs.append("--ssl-certificates-path=" + authServerHome + "/ca.crt ");
cliArgs.append("--ssl-client-certificate-file=" + authServerHome + "/client.crt ");
cliArgs.append("--ssl-client-key-file=" + authServerHome + "/client.key ");
cliArgs.append("--ssl-client-key-passphrase=secret ");
System.setProperty("keycloak.phantomjs.cli.args", cliArgs.toString());
}
}
}
@Before
public void configureFlows() {
authMgmtResource = adminClient.realms().realm(REALM_NAME).flows();
@ -301,6 +324,13 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe
.setUserIdentityMapperType(USERNAME_EMAIL);
}
protected static X509AuthenticatorConfigModel createLoginSubjectAltNameEmail2UsernameOrEmailConfig() {
return new X509AuthenticatorConfigModel()
.setConfirmationPageAllowed(true)
.setMappingSourceType(SUBJECTALTNAME_EMAIL)
.setUserIdentityMapperType(USERNAME_EMAIL);
}
protected static X509AuthenticatorConfigModel createLoginSubjectEmailWithKeyUsage(String keyUsage) {
return createLoginSubjectEmail2UsernameOrEmailConfig()
.setKeyUsage(keyUsage);

View file

@ -0,0 +1,97 @@
/*
* Copyright 2018 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.testsuite.x509;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel;
import org.keycloak.events.Details;
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.x509.X509IdentityConfirmationPage;
/**
* @author <a href="mailto:brat000012001@gmail.com">Peter Nalyvayko</a>
* @version $Revision: 1 $
* @date 8/12/2016
*/
public class X509BrowserLoginSubjectAltNameEmailTest extends AbstractX509AuthenticationTest {
@Page
protected AppPage appPage;
@Page
protected X509IdentityConfirmationPage loginConfirmationPage;
@Page
protected LoginPage loginPage;
@BeforeClass
public static void onBeforeTestClass() {
if (System.getProperty("auth.server.container", "undefined").endsWith("wildfly")) {
String authServerHome = System.getProperty("auth.server.home");
if (authServerHome != null && System.getProperty("auth.server.ssl.required") != null) {
authServerHome = authServerHome + "/standalone/configuration";
StringBuilder cliArgs = new StringBuilder();
cliArgs.append("--ignore-ssl-errors=true ");
cliArgs.append("--web-security=false ");
cliArgs.append("--ssl-certificates-path=" + authServerHome + "/ca.crt ");
cliArgs.append("--ssl-client-certificate-file=" + authServerHome + "/certs/clients/test-user-san-email@localhost.cert.pem ");
cliArgs.append("--ssl-client-key-file=" + authServerHome + "/certs/clients/test-user@localhost.key.pem ");
cliArgs.append("--ssl-client-key-passphrase=password");
System.setProperty("keycloak.phantomjs.cli.args", cliArgs.toString());
}
}
}
private void login(X509AuthenticatorConfigModel config, String userId, String username, String attemptedUsername) {
AuthenticatorConfigRepresentation cfg = newConfig("x509-browser-config", config.getConfig());
String cfgId = createConfig(browserExecution.getId(), cfg);
Assert.assertNotNull(cfgId);
loginConfirmationPage.open();
Assert.assertTrue(loginConfirmationPage.getSubjectDistinguishedNameText().equals("CN=test-user, OU=Keycloak, O=Red Hat, L=Boston, ST=MA, C=US"));
Assert.assertEquals(username, loginConfirmationPage.getUsernameText());
loginConfirmationPage.confirm();
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
events.expectLogin()
.user(userId)
.detail(Details.USERNAME, attemptedUsername)
.removeDetail(Details.REDIRECT_URI)
.assertEvent();
}
@Test
public void loginAsUserFromCertSubjectEmail() {
login(createLoginSubjectAltNameEmail2UsernameOrEmailConfig(), userId, "test-user@localhost", "test-user@localhost");
}
}

View file

@ -33,9 +33,6 @@
<property name="htmlUnit.version">${htmlUnitBrowserVersion}</property>
<property name="htmlUnitWebClientOptions">cssEnabled=false;historyPageCacheLimit=1</property>
<!-- phantomjs -->
<property name="phantomjs.cli.args">${phantomjs.cli.args}</property>
<!-- firefox -->
<property name="firefox_binary">${firefox_binary}</property>
<property name="firefoxLogLevel">OFF</property>

View file

@ -108,7 +108,6 @@
<js.browser>phantomjs</js.browser>
<js.chromeArguments>--headless</js.chromeArguments>
<htmlUnitBrowserVersion>chrome</htmlUnitBrowserVersion>
<phantomjs.cli.args>--ignore-ssl-errors=true --web-security=false --ssl-certificates-path=${client.certificate.ca.path} --ssl-client-certificate-file=${client.certificate.file} --ssl-client-key-file=${client.key.file} --ssl-client-key-passphrase=${client.key.passphrase}</phantomjs.cli.args>
<firefox_binary>/usr/bin/firefox</firefox_binary>
<firefoxLegacyDriver>true</firefoxLegacyDriver>
<chromeBinary/>
@ -285,7 +284,6 @@
<ieDriverArch>${ieDriverArch}</ieDriverArch>
<firefox_binary>${firefox_binary}</firefox_binary>
<phantomjs.cli.args>${phantomjs.cli.args}</phantomjs.cli.args>
<chromeBinary>${chromeBinary}</chromeBinary>
<chromeArguments>${chromeArguments}</chromeArguments>