Merge pull request #2649 from pdrozd/KEYCLOAK-2839
KEYCLOAK-2839 - kerberos tests migration.
This commit is contained in:
commit
069d362778
26 changed files with 1378 additions and 24 deletions
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.page;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pdrozd
|
||||
*/
|
||||
public class KerberosPortal extends AbstractPageWithInjectedUrl {
|
||||
|
||||
public static final String DEPLOYMENT_NAME = "kerberos-portal";
|
||||
|
||||
@ArquillianResource
|
||||
@OperateOnDeployment(DEPLOYMENT_NAME)
|
||||
private URL url;
|
||||
|
||||
@Override
|
||||
public URL getInjectedUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.security.sasl.Sasl;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.keycloak.KeycloakPrincipal;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.common.util.KerberosSerializationUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class KerberosCredDelegServlet extends HttpServlet {
|
||||
|
||||
public static final String CRED_DELEG_TEST_PATH = "/cred-deleg-test";
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String ldapData = null;
|
||||
|
||||
if (req.getRequestURI().endsWith(CRED_DELEG_TEST_PATH)) {
|
||||
|
||||
try {
|
||||
// Retrieve kerberos credential from accessToken and deserialize it
|
||||
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) req.getUserPrincipal();
|
||||
String serializedGssCredential = (String) keycloakPrincipal.getKeycloakSecurityContext().getToken().getOtherClaims().get(KerberosConstants.GSS_DELEGATION_CREDENTIAL);
|
||||
GSSCredential gssCredential = KerberosSerializationUtils.deserializeCredential(serializedGssCredential);
|
||||
|
||||
// First try to invoke without gssCredential. It should fail
|
||||
try {
|
||||
invokeLdap(null);
|
||||
throw new RuntimeException("Not expected to authenticate to LDAP without credential");
|
||||
} catch (NamingException nse) {
|
||||
System.out.println("Expected exception: " + nse.getMessage());
|
||||
}
|
||||
|
||||
ldapData = invokeLdap(gssCredential);
|
||||
} catch (KerberosSerializationUtils.KerberosSerializationException kse) {
|
||||
System.err.println("KerberosSerializationUtils.KerberosSerializationException: " + kse.getMessage());
|
||||
ldapData = "ERROR";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
resp.setContentType("text/html");
|
||||
PrintWriter pw = resp.getWriter();
|
||||
pw.printf("<html><head><title>%s</title></head><body>", "Kerberos Test");
|
||||
pw.printf("Kerberos servlet secured content<br>");
|
||||
|
||||
if (ldapData != null) {
|
||||
pw.printf("LDAP Data: " + ldapData + "<br>");
|
||||
}
|
||||
|
||||
pw.print("</body></html>");
|
||||
pw.flush();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private String invokeLdap(GSSCredential gssCredential) throws NamingException {
|
||||
Hashtable env = new Hashtable(11);
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
env.put(Context.PROVIDER_URL, "ldap://localhost:10389");
|
||||
|
||||
if (gssCredential != null) {
|
||||
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
|
||||
env.put(Sasl.CREDENTIALS, gssCredential);
|
||||
}
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
try {
|
||||
Attributes attrs = ctx.getAttributes("uid=hnelson,ou=People,dc=keycloak,dc=org");
|
||||
String cn = (String) attrs.get("cn").get();
|
||||
String sn = (String) attrs.get("sn").get();
|
||||
return cn + " " + sn;
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,18 +17,19 @@
|
|||
|
||||
package org.keycloak.testsuite.util;
|
||||
|
||||
import static org.keycloak.testsuite.util.IOUtil.PROJECT_BUILD_DIRECTORY;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -37,7 +38,8 @@ public class LDAPTestConfiguration {
|
|||
private static final Logger log = Logger.getLogger(LDAPTestConfiguration.class);
|
||||
|
||||
private String connectionPropertiesLocation;
|
||||
private boolean startEmbeddedLdapLerver = true;
|
||||
private int sleepTime;
|
||||
private boolean startEmbeddedLdapServer = true;
|
||||
private Map<String, String> config;
|
||||
|
||||
protected static final Map<String, String> PROP_MAPPINGS = new HashMap<String, String>();
|
||||
|
@ -83,8 +85,7 @@ public class LDAPTestConfiguration {
|
|||
DEFAULT_VALUES.put(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION, "false");
|
||||
DEFAULT_VALUES.put(KerberosConstants.KERBEROS_REALM, "KEYCLOAK.ORG");
|
||||
DEFAULT_VALUES.put(KerberosConstants.SERVER_PRINCIPAL, "HTTP/localhost@KEYCLOAK.ORG");
|
||||
URL keytabUrl = LDAPTestConfiguration.class.getResource("/kerberos/http.keytab");
|
||||
String keyTabPath = new File(keytabUrl.getFile()).getAbsolutePath();
|
||||
String keyTabPath = getResource("http.keytab");
|
||||
DEFAULT_VALUES.put(KerberosConstants.KEYTAB, keyTabPath);
|
||||
DEFAULT_VALUES.put(KerberosConstants.DEBUG, "true");
|
||||
DEFAULT_VALUES.put(KerberosConstants.ALLOW_PASSWORD_AUTHENTICATION, "true");
|
||||
|
@ -94,17 +95,22 @@ public class LDAPTestConfiguration {
|
|||
|
||||
public static LDAPTestConfiguration readConfiguration(String connectionPropertiesLocation) {
|
||||
LDAPTestConfiguration ldapTestConfiguration = new LDAPTestConfiguration();
|
||||
ldapTestConfiguration.setConnectionPropertiesLocation(connectionPropertiesLocation);
|
||||
ldapTestConfiguration.setConnectionPropertiesLocation(getResource(connectionPropertiesLocation));
|
||||
ldapTestConfiguration.loadConnectionProperties();
|
||||
return ldapTestConfiguration;
|
||||
}
|
||||
|
||||
public static String getResource(String resourceName) {
|
||||
return new File(PROJECT_BUILD_DIRECTORY, "dependency/kerberos/" + resourceName).getAbsolutePath();
|
||||
}
|
||||
|
||||
protected void loadConnectionProperties() {
|
||||
Properties p = new Properties();
|
||||
PropertiesConfiguration p;
|
||||
try {
|
||||
log.info("Reading LDAP configuration from: " + connectionPropertiesLocation);
|
||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(connectionPropertiesLocation);
|
||||
p.load(is);
|
||||
p = new PropertiesConfiguration();
|
||||
p.setDelimiterParsingDisabled(true);
|
||||
p.load(connectionPropertiesLocation);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -115,7 +121,7 @@ public class LDAPTestConfiguration {
|
|||
String propertyName = property.getKey();
|
||||
String configName = property.getValue();
|
||||
|
||||
String value = (String) p.get(configName);
|
||||
String value = p.getString(configName);
|
||||
if (value == null) {
|
||||
value = DEFAULT_VALUES.get(propertyName);
|
||||
}
|
||||
|
@ -123,8 +129,9 @@ public class LDAPTestConfiguration {
|
|||
config.put(propertyName, value);
|
||||
}
|
||||
|
||||
startEmbeddedLdapLerver = Boolean.parseBoolean(p.getProperty("idm.test.ldap.start.embedded.ldap.server", "true"));
|
||||
log.info("Start embedded server: " + startEmbeddedLdapLerver);
|
||||
startEmbeddedLdapServer = p.getBoolean("idm.test.ldap.start.embedded.ldap.server", true);
|
||||
sleepTime = p.getInteger("idm.test.ldap.sleepTime", 1000);
|
||||
log.info("Start embedded server: " + startEmbeddedLdapServer);
|
||||
log.info("Read config: " + config);
|
||||
}
|
||||
|
||||
|
@ -136,8 +143,12 @@ public class LDAPTestConfiguration {
|
|||
this.connectionPropertiesLocation = connectionPropertiesLocation;
|
||||
}
|
||||
|
||||
public boolean isStartEmbeddedLdapLerver() {
|
||||
return startEmbeddedLdapLerver;
|
||||
public boolean isStartEmbeddedLdapServer() {
|
||||
return startEmbeddedLdapServer;
|
||||
}
|
||||
|
||||
public int getSleepTime() {
|
||||
return sleepTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,10 +52,10 @@ import java.util.Map;
|
|||
*/
|
||||
public class AssertEvents {
|
||||
|
||||
static final String DEFAULT_CLIENT_ID = "test-app";
|
||||
static final String DEFAULT_IP_ADDRESS = "127.0.0.1";
|
||||
static final String DEFAULT_REALM = "test";
|
||||
static final String DEFAULT_USERNAME = "test-user@localhost";
|
||||
public static final String DEFAULT_CLIENT_ID = "test-app";
|
||||
public static final String DEFAULT_IP_ADDRESS = "127.0.0.1";
|
||||
public static final String DEFAULT_REALM = "test";
|
||||
public static final String DEFAULT_USERNAME = "test-user@localhost";
|
||||
|
||||
String defaultRedirectUri = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
String defaultEventsQueueUri = "http://localhost:8092";
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.federation;
|
||||
|
||||
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.client.params.AuthPolicy;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.adapters.HttpClientBuilder;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.page.KerberosPortal;
|
||||
import org.keycloak.testsuite.adapter.servlet.KerberosCredDelegServlet;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
import org.keycloak.testsuite.auth.page.account.ChangePassword;
|
||||
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||
import org.keycloak.util.ldap.KerberosEmbeddedServer;
|
||||
import org.keycloak.util.ldap.LDAPEmbeddedServer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public abstract class AbstractKerberosAdapterTest extends AbstractServletsAdapterTest {
|
||||
|
||||
protected static LDAPTestConfiguration ldapTestConfiguration;
|
||||
|
||||
protected KeycloakSPNegoSchemeFactory spnegoSchemeFactory;
|
||||
|
||||
protected ResteasyClient client;
|
||||
|
||||
protected static LDAPEmbeddedServer ldapEmbeddedServer;
|
||||
|
||||
protected AssertEvents events;
|
||||
|
||||
@Page
|
||||
protected ChangePassword changePasswordPage;
|
||||
|
||||
@Page
|
||||
protected KerberosPortal kerberosPortal;
|
||||
|
||||
protected abstract String getConnectionPropertiesLocation();
|
||||
|
||||
protected abstract CommonKerberosConfig getKerberosConfig(UserFederationProviderModel model);
|
||||
|
||||
@Deployment(name = KerberosPortal.DEPLOYMENT_NAME)
|
||||
protected static WebArchive kerberosPortal() {
|
||||
return servletDeployment(KerberosPortal.DEPLOYMENT_NAME, "keycloak.json", KerberosCredDelegServlet.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
|
||||
testRealms.add(loadRealm("/adapter-test/kerberosrealm.json"));
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
testRealmPage.setAuthRealm(AuthRealm.TEST);
|
||||
changePasswordPage.setAuthRealm(testRealmPage);
|
||||
ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(getConnectionPropertiesLocation());
|
||||
if (ldapTestConfiguration.isStartEmbeddedLdapServer() && ldapEmbeddedServer == null) {
|
||||
ldapEmbeddedServer = createServer();
|
||||
ldapEmbeddedServer.init();
|
||||
ldapEmbeddedServer.start();
|
||||
}
|
||||
// Global kerberos configuration
|
||||
String krb5ConfPath = LDAPTestConfiguration.getResource("test-krb5.conf");
|
||||
log.info("Krb5.conf file location is: " + krb5ConfPath);
|
||||
System.setProperty("java.security.krb5.conf", krb5ConfPath);
|
||||
events = new AssertEvents(this);
|
||||
UserFederationProviderModel model = new UserFederationProviderModel();
|
||||
model.setConfig(ldapTestConfiguration.getLDAPConfig());
|
||||
spnegoSchemeFactory = new KeycloakSPNegoSchemeFactory(getKerberosConfig(model));
|
||||
initHttpClient(true);
|
||||
removeAllUsers();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
client.close();
|
||||
client = null;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
try {
|
||||
if (ldapEmbeddedServer != null) {
|
||||
ldapEmbeddedServer.stop();
|
||||
ldapEmbeddedServer = null;
|
||||
ldapTestConfiguration = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error tearDown Embedded LDAP server.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spnegoNotAvailableTest() throws Exception {
|
||||
initHttpClient(false);
|
||||
|
||||
String kcLoginPageLocation = client.target(kerberosPortal.getInjectedUrl().toString()).request().get().getLocation().toString();
|
||||
|
||||
Response response = client.target(kcLoginPageLocation).request().get();
|
||||
Assert.assertEquals(401, response.getStatus());
|
||||
Assert.assertEquals(KerberosConstants.NEGOTIATE, response.getHeaderString(HttpHeaders.WWW_AUTHENTICATE));
|
||||
String responseText = response.readEntity(String.class);
|
||||
responseText.contains("Log in to test");
|
||||
response.close();
|
||||
}
|
||||
|
||||
protected void spnegoLoginTestImpl() throws Exception {
|
||||
Response spnegoResponse = spnegoLogin("hnelson", "secret");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
|
||||
List<UserRepresentation> users = testRealmResource().users().search("hnelson", 0, 1);
|
||||
String userId = users.get(0).getId();
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(userId)
|
||||
.detail(Details.REDIRECT_URI, kerberosPortal.toString())
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "hnelson")
|
||||
.assertEvent();
|
||||
|
||||
String location = spnegoResponse.getLocation().toString();
|
||||
driver.navigate().to(location);
|
||||
|
||||
String pageSource = driver.getPageSource();
|
||||
Assert.assertTrue(
|
||||
pageSource.contains("Kerberos Test") && pageSource.contains("Kerberos servlet secured content"));
|
||||
|
||||
spnegoResponse.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
// KEYCLOAK-2102
|
||||
@Test
|
||||
public void spnegoCaseInsensitiveTest() throws Exception {
|
||||
Response spnegoResponse = spnegoLogin("MyDuke", "theduke");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
List<UserRepresentation> users = testRealmResource().users().search("myduke", 0, 1);
|
||||
String userId = users.get(0).getId();
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(userId)
|
||||
.detail(Details.REDIRECT_URI, kerberosPortal.toString())
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "myduke")
|
||||
.assertEvent();
|
||||
|
||||
String location = spnegoResponse.getLocation().toString();
|
||||
driver.navigate().to(location);
|
||||
|
||||
String pageSource = driver.getPageSource();
|
||||
Assert.assertTrue(
|
||||
pageSource.contains("Kerberos Test") && pageSource.contains("Kerberos servlet secured content"));
|
||||
|
||||
spnegoResponse.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usernamePasswordLoginTest() throws Exception {
|
||||
// Change editMode to READ_ONLY
|
||||
updateProviderEditMode(UserFederationProvider.EditMode.READ_ONLY);
|
||||
|
||||
// Login with username/password from kerberos
|
||||
changePasswordPage.navigateTo();
|
||||
testRealmLoginPage.isCurrent();
|
||||
testRealmLoginPage.form().login("jduke", "theduke");
|
||||
changePasswordPage.isCurrent();
|
||||
|
||||
// Bad existing password
|
||||
changePasswordPage.changePasswords("theduke-invalid", "newPass", "newPass");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Invalid existing password."));
|
||||
|
||||
// Change password is not possible as editMode is READ_ONLY
|
||||
changePasswordPage.changePasswords("theduke", "newPass", "newPass");
|
||||
Assert.assertTrue(
|
||||
driver.getPageSource().contains("You can't update your password as your account is read only"));
|
||||
|
||||
// Change editMode to UNSYNCED
|
||||
updateProviderEditMode(UserFederationProvider.EditMode.UNSYNCED);
|
||||
|
||||
// Successfully change password now
|
||||
changePasswordPage.changePasswords("theduke", "newPass", "newPass");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Login with old password doesn't work, but with new password works
|
||||
testRealmLoginPage.form().login("jduke", "theduke");
|
||||
testRealmLoginPage.isCurrent();
|
||||
testRealmLoginPage.form().login("jduke", "newPass");
|
||||
changePasswordPage.isCurrent();
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Assert SPNEGO login still with the old password as mode is unsynced
|
||||
events.clear();
|
||||
Response spnegoResponse = spnegoLogin("jduke", "theduke");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), "jduke");
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(user != null ? user.getId() : null)
|
||||
.detail(Details.REDIRECT_URI, kerberosPortal.toString())
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "jduke")
|
||||
.assertEvent();
|
||||
spnegoResponse.close();
|
||||
}
|
||||
|
||||
|
||||
protected Response spnegoLogin(String username, String password) {
|
||||
kerberosPortal.navigateTo();
|
||||
Response res = client.target(kerberosPortal.getInjectedUrl().toString()).request().get();
|
||||
String kcLoginPageLocation = res.getLocation().toString();
|
||||
if (driver.manage().getCookieNamed("OAuth_Token_Request_State") != null) {
|
||||
kcLoginPageLocation = res.getLocation().toString().replaceFirst("state=.*&", "state=" + driver.manage().getCookieNamed("OAuth_Token_Request_State").getValue() + "&");
|
||||
}
|
||||
// Request for SPNEGO login sent with Resteasy client
|
||||
spnegoSchemeFactory.setCredentials(username, password);
|
||||
Response response = client.target(kcLoginPageLocation).request().get();
|
||||
if (response.getStatus() == 302) {
|
||||
if (response.getLocation() == null)
|
||||
return response;
|
||||
String uri = response.getLocation().toString();
|
||||
if (uri.contains("login-actions/required-action")) {
|
||||
response = client.target(uri).request().get();
|
||||
}
|
||||
}
|
||||
return response;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void initHttpClient(boolean useSpnego) {
|
||||
if (client != null) {
|
||||
after();
|
||||
}
|
||||
DefaultHttpClient httpClient = (DefaultHttpClient) new HttpClientBuilder().build();
|
||||
httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, spnegoSchemeFactory);
|
||||
|
||||
if (useSpnego) {
|
||||
Credentials fake = new Credentials() {
|
||||
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Principal getUserPrincipal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
httpClient.getCredentialsProvider().setCredentials(
|
||||
new AuthScope(null, -1, null),
|
||||
fake);
|
||||
}
|
||||
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
|
||||
client = new ResteasyClientBuilder().httpEngine(engine).build();
|
||||
}
|
||||
|
||||
protected void removeAllUsers() {
|
||||
RealmResource realm = testRealmResource();
|
||||
List<UserRepresentation> users = realm.users().search("", 0, Integer.MAX_VALUE);
|
||||
for (UserRepresentation user : users) {
|
||||
if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) {
|
||||
realm.users().get(user.getId()).remove();
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(1, realm.users().search("", 0, Integer.MAX_VALUE).size());
|
||||
}
|
||||
|
||||
protected void assertUser(String expectedUsername, String expectedEmail, String expectedFirstname,
|
||||
String expectedLastname, boolean updateProfileActionExpected) {
|
||||
try {
|
||||
UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), expectedUsername);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertEquals(expectedEmail, user.getEmail());
|
||||
Assert.assertEquals(expectedFirstname, user.getFirstName());
|
||||
Assert.assertEquals(expectedLastname, user.getLastName());
|
||||
|
||||
if (updateProfileActionExpected) {
|
||||
Assert.assertEquals(UserModel.RequiredAction.UPDATE_PROFILE.toString(),
|
||||
user.getRequiredActions().iterator().next());
|
||||
} else {
|
||||
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateProviderEditMode(UserFederationProvider.EditMode editMode) {
|
||||
RealmResource realm = testRealmResource();
|
||||
RealmRepresentation realmRepresentation = realm.toRepresentation();
|
||||
UserFederationProviderRepresentation kerberosProviderRepresentation = realmRepresentation
|
||||
.getUserFederationProviders().get(0);
|
||||
kerberosProviderRepresentation.getConfig().put(LDAPConstants.EDIT_MODE, editMode.toString());
|
||||
realm.update(realmRepresentation);
|
||||
}
|
||||
|
||||
public RealmResource testRealmResource() {
|
||||
return adminClient.realm("test");
|
||||
}
|
||||
|
||||
public Map<String, String> getConfig() {
|
||||
return ldapTestConfiguration.getLDAPConfig();
|
||||
}
|
||||
|
||||
protected static LDAPEmbeddedServer createServer() {
|
||||
Properties defaultProperties = new Properties();
|
||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY);
|
||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:kerberos/users-kerberos.ldif");
|
||||
return new KerberosEmbeddedServer(defaultProperties);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.federation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.kerberos.LDAPProviderKerberosConfig;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
|
||||
/**
|
||||
* Test of LDAPFederationProvider (Kerberos backed by LDAP)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public abstract class AbstractKerberosLdapAdapterTest extends AbstractKerberosAdapterTest {
|
||||
|
||||
private static final String PROVIDER_CONFIG_LOCATION = "kerberos-ldap-connection.properties";
|
||||
|
||||
@Before
|
||||
public void init() throws Exception{
|
||||
Map<String,String> ldapConfig = getConfig();
|
||||
UserFederationProviderRepresentation userFederationProviderRepresentation = new UserFederationProviderRepresentation();
|
||||
userFederationProviderRepresentation.setProviderName(LDAPFederationProviderFactory.PROVIDER_NAME);
|
||||
userFederationProviderRepresentation.setConfig(ldapConfig);
|
||||
userFederationProviderRepresentation.setPriority(0);
|
||||
userFederationProviderRepresentation.setDisplayName("kerberos-ldap");
|
||||
userFederationProviderRepresentation.setFullSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setChangedSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setLastSync(0);
|
||||
RealmRepresentation realmRepresentation = testRealmResource().toRepresentation();
|
||||
realmRepresentation.setUserFederationProviders(Arrays.asList(userFederationProviderRepresentation));
|
||||
realmRepresentation.setEventsEnabled(true);
|
||||
testRealmResource().update(realmRepresentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommonKerberosConfig getKerberosConfig(UserFederationProviderModel model) {
|
||||
return new LDAPProviderKerberosConfig(model);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spnegoLoginTest() throws Exception {
|
||||
spnegoLoginTestImpl();
|
||||
// Assert user was imported and hasn't any required action on him. Profile info is synced from LDAP
|
||||
assertUser("hnelson", "hnelson@keycloak.org", "Horatio", "Nelson", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writableEditModeTest() throws Exception {
|
||||
|
||||
// Change editMode to WRITABLE
|
||||
updateProviderEditMode(UserFederationProvider.EditMode.WRITABLE);
|
||||
|
||||
// Login with username/password from kerberos
|
||||
changePasswordPage.navigateTo();
|
||||
loginPage.isCurrent();
|
||||
loginPage.form().login("jduke", "theduke");
|
||||
changePasswordPage.isCurrent();
|
||||
|
||||
// Successfully change password now
|
||||
changePasswordPage.changePasswords("theduke", "newPass", "newPass");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Login with old password doesn't work, but with new password works
|
||||
loginPage.form().login("jduke", "theduke");
|
||||
loginPage.isCurrent();
|
||||
loginPage.form().login("jduke", "newPass");
|
||||
changePasswordPage.isCurrent();
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Assert SPNEGO login with the new password as mode is writable
|
||||
events.clear();
|
||||
Response spnegoResponse = spnegoLogin("jduke", "newPass");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), "jduke");
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(user != null ? user.getId() : null)
|
||||
.detail(Details.REDIRECT_URI, kerberosPortal.toString())
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "jduke")
|
||||
.assertEvent();
|
||||
|
||||
// Change password back
|
||||
changePasswordPage.navigateTo();;
|
||||
|
||||
loginPage.form().login("jduke", "newPass");
|
||||
changePasswordPage.isCurrent();
|
||||
changePasswordPage.changePasswords("newPass", "theduke", "theduke");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logOut();
|
||||
|
||||
spnegoResponse.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
protected String getConnectionPropertiesLocation() {
|
||||
return PROVIDER_CONFIG_LOCATION;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.federation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.federation.kerberos.KerberosConfig;
|
||||
import org.keycloak.federation.kerberos.KerberosFederationProviderFactory;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxProfile;
|
||||
|
||||
/**
|
||||
* Test of KerberosFederationProvider (Kerberos not backed by LDAP)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public abstract class AbstractKerberosStandaloneAdapterTest extends AbstractKerberosAdapterTest {
|
||||
|
||||
protected static final String PROVIDER_CONFIG_LOCATION = "kerberos-standalone-connection.properties";
|
||||
|
||||
@Before
|
||||
public void init() throws Exception{
|
||||
Map<String,String> ldapConfig = getConfig();
|
||||
UserFederationProviderRepresentation userFederationProviderRepresentation = new UserFederationProviderRepresentation();
|
||||
userFederationProviderRepresentation.setProviderName(KerberosFederationProviderFactory.PROVIDER_NAME);
|
||||
userFederationProviderRepresentation.setConfig(ldapConfig);
|
||||
userFederationProviderRepresentation.setPriority(0);
|
||||
userFederationProviderRepresentation.setDisplayName("kerberos-standalone");
|
||||
userFederationProviderRepresentation.setFullSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setChangedSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setLastSync(0);
|
||||
|
||||
RealmRepresentation realmRepresentation = testRealmResource().toRepresentation();
|
||||
realmRepresentation.setUserFederationProviders(Arrays.asList(userFederationProviderRepresentation));
|
||||
realmRepresentation.setEventsEnabled(true);
|
||||
testRealmResource().update(realmRepresentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommonKerberosConfig getKerberosConfig(UserFederationProviderModel model) {
|
||||
return new KerberosConfig(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getConnectionPropertiesLocation() {
|
||||
return PROVIDER_CONFIG_LOCATION;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spnegoLoginTest() throws Exception {
|
||||
spnegoLoginTestImpl();
|
||||
// Assert user was imported and hasn't any required action on him
|
||||
assertUser("hnelson", "hnelson@keycloak.org", null, null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void usernamePasswordLoginTest() throws Exception {
|
||||
super.usernamePasswordLoginTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateProfileEnabledTest() throws Exception {
|
||||
// Switch updateProfileOnFirstLogin to on
|
||||
RealmRepresentation realm = testRealmResource().toRepresentation();
|
||||
UserFederationProviderRepresentation kerberosProviderRepresentation = realm.getUserFederationProviders().get(0);
|
||||
kerberosProviderRepresentation.getConfig().put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "true");
|
||||
testRealmResource().update(realm);
|
||||
|
||||
// Assert update profile page is displayed
|
||||
Response spnegoResponse = spnegoLogin("hnelson", "secret");
|
||||
Assert.assertEquals(200, spnegoResponse.getStatus());
|
||||
String responseText = spnegoResponse.readEntity(String.class);
|
||||
Assert.assertTrue(responseText.contains("You need to update your user profile to activate your account."));
|
||||
Assert.assertTrue(responseText.contains("hnelson@keycloak.org"));
|
||||
spnegoResponse.close();
|
||||
|
||||
// Assert user was imported and has required action on him
|
||||
assertUser("hnelson", "hnelson@keycloak.org", null, null, true);
|
||||
|
||||
// Switch updateProfileOnFirstLogin to off
|
||||
|
||||
kerberosProviderRepresentation = realm.getUserFederationProviders().get(0);
|
||||
kerberosProviderRepresentation.getConfig().put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "false");
|
||||
testRealmResource().update(realm);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2016 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.adapter.federation;
|
||||
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.impl.auth.SPNegoScheme;
|
||||
import org.apache.http.impl.auth.SPNegoSchemeFactory;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.ietf.jgss.GSSContext;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.GSSName;
|
||||
import org.ietf.jgss.Oid;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.federation.kerberos.impl.KerberosUsernamePasswordAuthenticator;
|
||||
|
||||
/**
|
||||
* Usable for testing only. Username and password are shared for the whole factory
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class KeycloakSPNegoSchemeFactory extends SPNegoSchemeFactory {
|
||||
|
||||
private final CommonKerberosConfig kerberosConfig;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
|
||||
public KeycloakSPNegoSchemeFactory(CommonKerberosConfig kerberosConfig) {
|
||||
super(true, false);
|
||||
this.kerberosConfig = kerberosConfig;
|
||||
}
|
||||
|
||||
|
||||
public void setCredentials(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AuthScheme newInstance(HttpParams params) {
|
||||
return new KeycloakSPNegoScheme(isStripPort(), isUseCanonicalHostname());
|
||||
}
|
||||
|
||||
|
||||
public class KeycloakSPNegoScheme extends SPNegoScheme {
|
||||
|
||||
public KeycloakSPNegoScheme(boolean stripPort, boolean useCanonicalHostname) {
|
||||
super(stripPort, useCanonicalHostname);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected byte[] generateGSSToken(byte[] input, Oid oid, String authServer, Credentials credentials) throws GSSException {
|
||||
KerberosUsernamePasswordAuthenticator authenticator = new KerberosUsernamePasswordAuthenticator(kerberosConfig);
|
||||
try {
|
||||
Subject clientSubject = authenticator.authenticateSubject(username, password);
|
||||
|
||||
ByteArrayHolder holder = Subject.doAs(clientSubject, new ClientAcceptSecContext(input, oid, authServer));
|
||||
|
||||
return holder.bytes;
|
||||
} catch (Exception le) {
|
||||
throw new RuntimeException(le);
|
||||
} finally {
|
||||
authenticator.logoutSubject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ClientAcceptSecContext implements PrivilegedExceptionAction<ByteArrayHolder> {
|
||||
|
||||
private final byte[] input;
|
||||
private final Oid oid;
|
||||
private final String authServer;
|
||||
|
||||
public ClientAcceptSecContext(byte[] input, Oid oid, String authServer) {
|
||||
this.input = input;
|
||||
this.oid = oid;
|
||||
this.authServer = authServer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ByteArrayHolder run() throws Exception {
|
||||
byte[] token = input;
|
||||
if (token == null) {
|
||||
token = new byte[0];
|
||||
}
|
||||
GSSManager manager = getManager();
|
||||
GSSName serverName = manager.createName("HTTP/" + authServer + "@" + kerberosConfig.getKerberosRealm(), null);
|
||||
GSSContext gssContext = manager.createContext(
|
||||
serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME);
|
||||
gssContext.requestMutualAuth(true);
|
||||
gssContext.requestCredDeleg(true);
|
||||
byte[] outputToken = gssContext.initSecContext(token, 0, token.length);
|
||||
|
||||
ByteArrayHolder result = new ByteArrayHolder();
|
||||
result.bytes = outputToken;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class ByteArrayHolder {
|
||||
private byte[] bytes;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
~ Copyright 2016 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.
|
||||
-->
|
||||
|
||||
<Context path="/kerberos-portal">
|
||||
<Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
|
||||
</Context>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Copyright 2016 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.
|
||||
-->
|
||||
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Get name="securityHandler">
|
||||
<Set name="authenticator">
|
||||
<New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
|
||||
</New>
|
||||
</Set>
|
||||
</Get>
|
||||
</Configure>
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"realm" : "test",
|
||||
"resource" : "kerberos-app",
|
||||
"auth-server-url" : "/auth",
|
||||
"ssl-required" : "external",
|
||||
"credentials" : {
|
||||
"secret": "password"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"realm": "test",
|
||||
"resource": "kerberos-app",
|
||||
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"auth-server-url": "http://localhost:8081/auth",
|
||||
"ssl-required" : "external",
|
||||
"credentials": {
|
||||
"secret": "password"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 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.
|
||||
-->
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
|
||||
<module-name>kerberos-portal</module-name>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Servlet</servlet-name>
|
||||
<servlet-class>org.keycloak.testsuite.adapter.servlet.KerberosCredDelegServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>Servlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Users</web-resource-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>user</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<login-config>
|
||||
<auth-method>KEYCLOAK</auth-method>
|
||||
<realm-name>test</realm-name>
|
||||
</login-config>
|
||||
|
||||
<security-role>
|
||||
<role-name>admin</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<role-name>user</role-name>
|
||||
</security-role>
|
||||
</web-app>
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"id": "test",
|
||||
"realm": "test",
|
||||
"enabled": true,
|
||||
"sslRequired": "external",
|
||||
"registrationAllowed": true,
|
||||
"resetPasswordAllowed": true,
|
||||
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"requiredCredentials": [ "password", "kerberos" ],
|
||||
"defaultRoles": [ "user" ],
|
||||
"users" : [
|
||||
{
|
||||
"username" : "test-user@localhost",
|
||||
"enabled": true,
|
||||
"email" : "test-user@localhost",
|
||||
"credentials" : [
|
||||
{ "type" : "password",
|
||||
"value" : "password" }
|
||||
],
|
||||
"realmRoles": ["user"],
|
||||
"applicationRoles": {
|
||||
"account": [ "view-profile", "manage-account" ]
|
||||
}
|
||||
}
|
||||
],
|
||||
"scopeMappings": [
|
||||
{
|
||||
"client": "kerberos-app",
|
||||
"roles": ["user"]
|
||||
}
|
||||
],
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "kerberos-app",
|
||||
"enabled": true,
|
||||
"adminUrl": "/kerberos-portal/logout",
|
||||
"baseUrl": "/kerberos-portal",
|
||||
"redirectUris": [
|
||||
"/kerberos-portal/*"
|
||||
],
|
||||
"secret": "password"
|
||||
}
|
||||
],
|
||||
"roles" : {
|
||||
"realm" : [
|
||||
{
|
||||
"name": "user",
|
||||
"description": "Have User privileges"
|
||||
}
|
||||
]
|
||||
},
|
||||
"eventsListeners": ["jboss-logging", "event-queue"]
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# Copyright 2016 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.
|
||||
#
|
||||
|
||||
idm.test.ldap.connection.url=ldap\://localhost\:10389
|
||||
idm.test.ldap.base.dn=dc\=keycloak,dc\=org
|
||||
idm.test.ldap.roles.dn.suffix=ou\=Roles,dc\=keycloak,dc\=org
|
||||
idm.test.ldap.group.dn.suffix=ou\=Groups,dc\=keycloak,dc\=org
|
||||
idm.test.ldap.user.dn.suffix=ou\=People,dc\=keycloak,dc\=org
|
||||
idm.test.ldap.start.embedded.ldap.server=true
|
||||
idm.test.ldap.bind.dn=uid\=admin,ou\=system
|
||||
idm.test.ldap.bind.credential=secret
|
||||
idm.test.ldap.connection.pooling=true
|
||||
idm.test.ldap.pagination=true
|
||||
idm.test.ldap.batch.size.for.sync=3
|
||||
|
||||
idm.test.kerberos.allow.kerberos.authentication=true
|
||||
idm.test.kerberos.realm=KEYCLOAK.ORG
|
||||
idm.test.kerberos.server.principal=HTTP/localhost@KEYCLOAK.ORG
|
||||
idm.test.kerberos.debug=true
|
||||
idm.test.kerberos.use.kerberos.for.password.authentication=true
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# Copyright 2016 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.
|
||||
#
|
||||
|
||||
idm.test.kerberos.allow.kerberos.authentication=true
|
||||
idm.test.kerberos.realm=KEYCLOAK.ORG
|
||||
idm.test.kerberos.server.principal=HTTP/localhost@KEYCLOAK.ORG
|
||||
idm.test.kerberos.debug=false
|
||||
idm.test.kerberos.allow.password.authentication=true
|
||||
idm.test.kerberos.update.profile.first.login=false
|
|
@ -0,0 +1,19 @@
|
|||
[libdefaults]
|
||||
default_realm = KEYCLOAK.ORG
|
||||
default_tgs_enctypes = des3-cbc-sha1-kd aes256-cts-hmac-sha1-96 rc4-hmac aes128-cts-hmac-sha1-96
|
||||
default_tkt_enctypes = des3-cbc-sha1-kd aes256-cts-hmac-sha1-96 rc4-hmac aes128-cts-hmac-sha1-96
|
||||
permitted_enctypes = des3-cbc-sha1-kd aes256-cts-hmac-sha1-96 rc4-hmac aes128-cts-hmac-sha1-96
|
||||
kdc_timeout = 30000
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = false
|
||||
dns_canonicalize_hostname = false
|
||||
ignore_acceptor_hostname = true
|
||||
forwardable = true
|
||||
|
||||
[realms]
|
||||
KEYCLOAK.ORG = {
|
||||
kdc = localhost:6088
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
localhost = KEYCLOAK.ORG
|
|
@ -0,0 +1,104 @@
|
|||
dn: dc=keycloak,dc=org
|
||||
objectclass: dcObject
|
||||
objectclass: organization
|
||||
o: Keycloak
|
||||
dc: Keycloak
|
||||
|
||||
dn: ou=People,dc=keycloak,dc=org
|
||||
objectClass: organizationalUnit
|
||||
objectClass: top
|
||||
ou: People
|
||||
|
||||
dn: uid=krbtgt,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: KDC Service
|
||||
sn: Service
|
||||
uid: krbtgt
|
||||
userPassword: secret
|
||||
krb5PrincipalName: krbtgt/KEYCLOAK.ORG@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=ldap,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: LDAP
|
||||
sn: Service
|
||||
uid: ldap
|
||||
userPassword: randall
|
||||
krb5PrincipalName: ${ldapSaslPrincipal}
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=HTTP,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: HTTP
|
||||
sn: Service
|
||||
uid: HTTP
|
||||
userPassword: httppwd
|
||||
krb5PrincipalName: HTTP/${hostname}@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=hnelson,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: Horatio
|
||||
sn: Nelson
|
||||
mail: hnelson@keycloak.org
|
||||
uid: hnelson
|
||||
userPassword: secret
|
||||
krb5PrincipalName: hnelson@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=jduke,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: Java
|
||||
sn: Duke
|
||||
mail: jduke@keycloak.org
|
||||
uid: jduke
|
||||
userPassword: theduke
|
||||
krb5PrincipalName: jduke@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=MyDuke,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: My
|
||||
sn: Duke
|
||||
mail: MyDuke@keycloak.org
|
||||
uid: MyDuke
|
||||
userPassword: theduke
|
||||
krb5PrincipalName: MyDuke@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
||||
|
||||
dn: uid=gsstestserver,ou=People,dc=keycloak,dc=org
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: krb5principal
|
||||
objectClass: krb5kdcentry
|
||||
cn: gsstestserver
|
||||
sn: Service
|
||||
uid: gsstestserver
|
||||
userPassword: gsstestpwd
|
||||
krb5PrincipalName: gsstestserver/xxx@KEYCLOAK.ORG
|
||||
krb5KeyVersionNumber: 0
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosLdapAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
@AppServerContainer("app-server-eap")
|
||||
public class EAPOIDCKerberosLdapAdapterTest extends AbstractKerberosLdapAdapterTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosStandaloneAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
@AppServerContainer("app-server-eap")
|
||||
public class EAPOIDCKerberosStandaloneAdapterTest extends AbstractKerberosStandaloneAdapterTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosLdapAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pdrozd
|
||||
*/
|
||||
@AppServerContainer("app-server-eap6")
|
||||
public class EAP6OIDCKerberosLdapAdapterTest extends AbstractKerberosLdapAdapterTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosStandaloneAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pdrozd
|
||||
*/
|
||||
@AppServerContainer("app-server-eap6")
|
||||
public class EAP6OIDCKerberosStandaloneAdapterTest extends AbstractKerberosStandaloneAdapterTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosLdapAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pdrozd
|
||||
*/
|
||||
@AppServerContainer("app-server-wildfly")
|
||||
public class WildflyOIDCKerberosLdapAdapterTest extends AbstractKerberosLdapAdapterTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.testsuite.adapter;
|
||||
|
||||
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.testsuite.adapter.federation.AbstractKerberosStandaloneAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pdrozd
|
||||
*/
|
||||
@AppServerContainer("app-server-wildfly")
|
||||
public class WildflyOIDCKerberosStandaloneAdapterTest extends AbstractKerberosStandaloneAdapterTest {
|
||||
|
||||
}
|
|
@ -59,7 +59,7 @@
|
|||
<artifactId>integration-arquillian-tests-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<includes>arquillian.xml,keycloak-add-user.json</includes>
|
||||
<includes>arquillian.xml,keycloak-add-user.json,kerberos/*</includes>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
|
|
Loading…
Reference in a new issue