package org.infinispan.test.integration.security.embedded;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.Context;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import org.infinispan.security.AuthorizationPermission;
import org.infinispan.security.PrincipalRoleMapper;
import org.infinispan.test.integration.security.tasks.AbstractKrb5ConfServerSetupTask;
import org.infinispan.test.integration.security.tasks.AbstractSecurityDomainsServerSetupTask;
import org.infinispan.test.integration.security.tasks.AbstractSystemPropertiesServerSetupTask;
import org.infinispan.test.integration.security.tasks.AbstractTraceLoggingServerSetupTask;
import org.infinispan.test.integration.security.utils.ApacheDsKrbLdap;
import org.infinispan.test.integration.security.utils.Deployments;
import org.infinispan.test.integration.security.utils.SimplePrincipalGroupRoleMapper;
import org.infinispan.test.integration.security.utils.Utils;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.TargetsContainer;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.as.arquillian.api.ServerSetup;
import org.jboss.as.arquillian.api.ServerSetupTask;
import org.jboss.as.arquillian.container.ManagementClient;
import org.jboss.as.test.integration.security.common.config.SecurityDomain;
import org.jboss.as.test.integration.security.common.config.SecurityModule;
import org.jboss.security.SecurityConstants;
import org.jboss.security.negotiation.AdvancedLdapLoginModule;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.runner.RunWith;
/**
* @author <a href="mailto:vjuranek@redhat.com">Vojtech Juranek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
* @since 7.0
*/
@RunWith(Arquillian.class)
@ServerSetup({
KrbLdapAuthenticationIT.KerberosSystemPropertiesSetupTask.class,
KrbLdapAuthenticationIT.SecurityDomainsSetupTask.class,
KrbLdapAuthenticationIT.SecurityTraceLoggingServerSetupTask.class,
KrbLdapAuthenticationIT.KrbLdapServerSetupTask.class,
KrbLdapAuthenticationIT.Krb5ConfServerSetupTask.class
})
public class KrbLdapAuthenticationIT extends AbstractAuthentication {
private static final String TRUE = Boolean.TRUE.toString(); // TRUE
public static final String ADMIN_ROLE = "AdminIspnRole";
public static final String WRITER_ROLE = "WriterIspnRole";
public static final String READER_ROLE = "ReaderIspnRole";
public static final String UNPRIVILEGED_ROLE = "UnprivilegedIspnRole";
@Deployment
@TargetsContainer(DEFAULT_DEPLOY_CONTAINER)
public static WebArchive getDeployment() {
return Deployments.createKrbLdapTestDeployment();
}
public Map<String, AuthorizationPermission[]> getRolePermissionMap() {
Map<String, AuthorizationPermission[]> roles = new HashMap<String, AuthorizationPermission[]>();
roles.put(ADMIN_ROLE, new AuthorizationPermission[]{AuthorizationPermission.ALL});
roles.put(WRITER_ROLE, new AuthorizationPermission[]{AuthorizationPermission.WRITE});
roles.put(READER_ROLE, new AuthorizationPermission[]{AuthorizationPermission.READ});
roles.put(UNPRIVILEGED_ROLE, new AuthorizationPermission[]{AuthorizationPermission.NONE});
return roles;
}
public PrincipalRoleMapper getPrincipalRoleMapper() {
return new SimplePrincipalGroupRoleMapper();
}
public String getSecurityDomainName() {
return null; //not used in this test
}
public Subject getAdminSubject() throws LoginException {
return authenticateWithKrb("ispn-admin");
}
public Subject getWriterSubject() throws LoginException {
return authenticateWithKrb("ispn-writer");
}
public Subject getReaderSubject() throws LoginException {
return authenticateWithKrb("ispn-reader");
}
public Subject getUnprivilegedSubject() throws LoginException {
return authenticateWithKrb("ispn-unprivileged");
}
/**
* A {@link ServerSetupTask} instance which creates security domains for this test case.
*
* @author <a href="mailto:jcacek@redhat.com">Josef Cacek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
*/
static class SecurityDomainsSetupTask extends AbstractSecurityDomainsServerSetupTask {
/**
* Returns SecurityDomains configuration for this testcase.
*/
@Override
protected SecurityDomain[] getSecurityDomains() {
final String host = Utils.getCannonicalHost(managementClient);
final SecurityDomain krbLdapServiceDomain = getKrbSecurityDomain("ldap-service", "ldap/" + host, true);
final SecurityDomain krbAdminDomain = getKrbSecurityDomain("admin", "admin", false);
final SecurityDomain krbWriterDomain = getKrbSecurityDomain("writer", "writer", false);
final SecurityDomain krbReaderDomain = getKrbSecurityDomain("reader", "reader", false);
final SecurityDomain krbUnprivDomain = getKrbSecurityDomain("unprivileged", "unprivileged", false);
final SecurityDomain spnegoAdminDomain = getSpnegoSecurityDomain("admin", managementClient, 10389, "ldap-service");
final SecurityDomain spnegoWriterDomain = getSpnegoSecurityDomain("writer", managementClient, 10389, "ldap-service");
final SecurityDomain spnegoReaderDomain = getSpnegoSecurityDomain("reader", managementClient, 10389, "ldap-service");
final SecurityDomain spnegoUnprivDomain = getSpnegoSecurityDomain("unprivileged", managementClient, 10389, "ldap-service");
return new SecurityDomain[]{
krbLdapServiceDomain,
krbAdminDomain, krbWriterDomain, krbReaderDomain, krbUnprivDomain,
spnegoAdminDomain, spnegoWriterDomain, spnegoReaderDomain, spnegoUnprivDomain
};
}
private SecurityDomain getKrbSecurityDomain(String name, String principal, boolean isService) {
final SecurityModule.Builder krbModuleBuilder = new SecurityModule.Builder();
if (Utils.IBM_JDK) {
krbModuleBuilder.name("com.ibm.security.auth.module.Krb5LoginModule") //
.putOption("useKeytab", "${java.io.tmpdir}" + File.separator + "keytabs" + File.separator + name + ".keytab"); //
if (isService) {
krbModuleBuilder.putOption("credsType", "both") //
.putOption("forwardable", TRUE) //
.putOption("proxiable", TRUE) //
.putOption("noAddress", TRUE);
} else
krbModuleBuilder.putOption("credsType", "acceptor");
} else {
krbModuleBuilder.name("Kerberos")
.putOption("useKeyTab", TRUE)
.putOption("keyTab", "${java.io.tmpdir}" + File.separator + "keytabs" + File.separator + name + ".keytab"); //
if (isService) {
krbModuleBuilder
.putOption("storeKey", TRUE)
.putOption("refreshKrb5Config", TRUE)
.putOption("doNotPrompt", TRUE);
}
}
krbModuleBuilder
.putOption("principal", principal + "@INFINISPAN.ORG")
.putOption("debug", TRUE);
return new SecurityDomain.Builder().name("krb-" + name)
.cacheType("default")
.loginModules(krbModuleBuilder.build())
.build();
}
private static SecurityDomain getSpnegoSecurityDomain(String user, ManagementClient managementClient, int ldapPort, String ldapServiceName) {
final String host = Utils.getCannonicalHost(managementClient);
return new SecurityDomain.Builder()
.name("ispn-" + user)
.cacheType("default")
.loginModules(
new SecurityModule.Builder().name("SPNEGO").flag("requisite")
.putOption("password-stacking", "useFirstPass")
.putOption("serverSecurityDomain", "krb-" + ldapServiceName)
.putOption("usernamePasswordDomain", "krb-" + user)
.build(),
new SecurityModule.Builder().name(AdvancedLdapLoginModule.class.getName())
.putOption("password-stacking", "useFirstPass")
// .putOption("bindAuthentication", "simple")
// .putOption("bindCredential", "secret")
// .putOption("bindDN", "uid=admin,ou=system")
.putOption("bindAuthentication", "GSSAPI")
.putOption("jaasSecurityDomain", "krb-" + ldapServiceName)
.putOption(Context.PROVIDER_URL,
"ldap://" + host + ":" + ldapPort)
.putOption("baseCtxDN", "ou=People,dc=infinispan,dc=org")
.putOption("baseFilter", "(krb5PrincipalName={0})")
.putOption("rolesCtxDN", "ou=Roles,dc=infinispan,dc=org")
.putOption("roleFilter", "(member={1})")
.putOption("roleAttributeID", "cn")
.build())
.build();
}
}
/**
* A Kerberos system-properties server setup task. Sets path to a <code>krb5.conf</code> file and enables Kerberos
* debug messages.
*
* @author <a href="mailto:jcacek@redhat.com">Josef Cacek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
*/
static class KerberosSystemPropertiesSetupTask extends AbstractSystemPropertiesServerSetupTask {
/**
* Returns "java.security.krb5.conf" and "sun.security.krb5.debug" properties.
*
* @return Kerberos properties
*/
@Override
protected SystemProperty[] getSystemProperties() {
final Map<String, String> map = new HashMap<>();
map.put("java.security.krb5.conf", "${java.io.tmpdir}" + File.separator + "krb5.conf");
map.put("java.security.krb5.debug", TRUE);
map.put(SecurityConstants.DISABLE_SECDOMAIN_OPTION, TRUE);
return mapToSystemProperties(map);
}
}
/**
* A Trace logging server setup task. Sets trace logging for specified packages
*
* @author <a href="mailto:jcacek@redhat.com">Josef Cacek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
*/
static class SecurityTraceLoggingServerSetupTask extends AbstractTraceLoggingServerSetupTask {
@Override
protected Collection<String> getCategories(ManagementClient managementClient, String containerId) {
return Arrays.asList("javax.security", "org.jboss.security", "org.picketbox");
}
}
/**
* A Kerberos/Ldap server setup task. Starts Kerberos/Ldap server
*
* @author <a href="mailto:jcacek@redhat.com">Josef Cacek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
*/
static class KrbLdapServerSetupTask implements ServerSetupTask {
private static ApacheDsKrbLdap krbLdapServer;
@Override
public void setup(ManagementClient managementClient, String s) throws Exception {
final String hostname = Utils.getCannonicalHost(managementClient);
System.setProperty("java.security.krb5.conf", Utils.getResource("krb5.conf").getPath());
krbLdapServer = new ApacheDsKrbLdap(hostname);
krbLdapServer.start();
}
@Override
public void tearDown(ManagementClient managementClient, String s) throws Exception {
krbLdapServer.stop();
}
}
/**
* Generate kerberos keytabs for infinispan users and ldap service
*
* @author <a href="mailto:jcacek@redhat.com">Josef Cacek</a>
* @author <a href="mailto:vchepeli@redhat.com">Vitalii Chepeliuk</a>
*/
static class Krb5ConfServerSetupTask extends AbstractKrb5ConfServerSetupTask {
public static final File ADMIN_KEYTAB_FILE = new File(KEYTABS_DIR, "admin.keytab");
public static final File WRITER_KEYTAB_FILE = new File(KEYTABS_DIR, "writer.keytab");
public static final File READER_KEYTAB_FILE = new File(KEYTABS_DIR, "reader.keytab");
public static final File UNPRIV_KEYTAB_FILE = new File(KEYTABS_DIR, "unprivileged.keytab");
@Override
protected List<UserForKeyTab> kerberosUsers() {
List<UserForKeyTab> users = new ArrayList<>();
users.add(new UserForKeyTab("admin@INFINISPAN.ORG", "strongPassword", ADMIN_KEYTAB_FILE));
users.add(new UserForKeyTab("writer@INFINISPAN.ORG", "somePassword", WRITER_KEYTAB_FILE));
users.add(new UserForKeyTab("reader@INFINISPAN.ORG", "password", READER_KEYTAB_FILE));
users.add(new UserForKeyTab("unprivileged@INFINISPAN.ORG", "weakPassword", UNPRIV_KEYTAB_FILE));
return users;
}
}
}