package org.infinispan.test.integration.security.embedded; import static org.junit.Assert.assertEquals; import java.security.PrivilegedExceptionAction; import java.util.Map; import java.util.Map.Entry; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.infinispan.Cache; import org.infinispan.configuration.cache.AuthorizationConfigurationBuilder; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalAuthorizationConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.configuration.global.GlobalRoleConfigurationBuilder; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.security.AuthorizationPermission; import org.infinispan.security.PrincipalRoleMapper; import org.infinispan.security.Security; import org.infinispan.test.integration.security.utils.LoginHandler; import org.infinispan.transaction.LockingMode; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * @author <a href="mailto:vjuranek@redhat.com">Vojtech Juranek</a> * @since 7.0 */ public abstract class AbstractAuthentication { public static final String DEFAULT_DEPLOY_CONTAINER = "testnode"; public static final String CACHE_NAME = "secureCache"; public static final String TEST_ENTRY_VALUE = "predefined value"; protected EmbeddedCacheManager manager; public static final String TEST_ENTRY_KEY = "predefined key"; protected Cache<Object, Object> secureCache; private GlobalConfigurationBuilder globalConfig; private ConfigurationBuilder cacheConfig; public abstract String getSecurityDomainName(); public abstract Map<String, AuthorizationPermission[]> getRolePermissionMap(); public abstract PrincipalRoleMapper getPrincipalRoleMapper(); public abstract Subject getAdminSubject() throws LoginException; public abstract Subject getWriterSubject() throws LoginException; public abstract Subject getReaderSubject() throws LoginException; public abstract Subject getUnprivilegedSubject() throws LoginException; public Subject authenticate(String login, String password) throws LoginException { final String securityDomain = System.getProperty("jboss.security.domain", getSecurityDomainName()); LoginContext lc = new LoginContext(securityDomain, new LoginHandler(login, password)); lc.login(); return lc.getSubject(); } public Subject authenticateWithKrb(String krbSecurityDomain) throws LoginException { LoginContext lc = new LoginContext(krbSecurityDomain, new LoginHandler(null, null)); lc.login(); return lc.getSubject(); } @Before public void setupCache() throws Exception { //global setup globalConfig = new GlobalConfigurationBuilder(); globalConfig.globalJmxStatistics().disable(); globalConfig.globalJmxStatistics().mBeanServerLookup(null); //TODO remove once WFLY-3124 is fixed, for now fail JMX registration GlobalAuthorizationConfigurationBuilder globalRoles = globalConfig.security().authorization().enable() .principalRoleMapper(getPrincipalRoleMapper()); //cache setup cacheConfig = new ConfigurationBuilder(); cacheConfig.transaction().lockingMode(LockingMode.PESSIMISTIC); cacheConfig.invocationBatching().enable(); cacheConfig.jmxStatistics().disable(); AuthorizationConfigurationBuilder authConfig = cacheConfig.security().authorization().enable(); //authorization setup Map<String, AuthorizationPermission[]> rolePermissionMap = getRolePermissionMap(); for (Entry<String, AuthorizationPermission[]> role : rolePermissionMap.entrySet()) { authConfig = authConfig.role(role.getKey()); GlobalRoleConfigurationBuilder roleBuilder = globalRoles.role(role.getKey()); for (AuthorizationPermission permission : role.getValue()) { roleBuilder = roleBuilder.permission(permission); } } Subject admin = getAdminSubject(); Security.doAs(admin, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { manager = new DefaultCacheManager(globalConfig.build()); manager.defineConfiguration(CACHE_NAME, cacheConfig.build()); secureCache = manager.getCache(CACHE_NAME); secureCache.put(TEST_ENTRY_KEY, TEST_ENTRY_VALUE); return null; } }); } @After public void tearDown() throws Exception { if (manager != null) { Subject admin = getAdminSubject(); Security.doAs(admin, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { manager.stop(); return null; } }); } } @Test public void testAdminCRUD() throws Exception { Subject admin = getAdminSubject(); Security.doAs(admin, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { assertEquals(TEST_ENTRY_VALUE, secureCache.get(TEST_ENTRY_KEY)); secureCache.putIfAbsent("test", "test value"); assertEquals("test value", secureCache.get("test")); secureCache.put("test", "test value2"); assertEquals("test value2", secureCache.get("test")); secureCache.remove("test"); assertEquals(null, secureCache.get("test")); secureCache.clear(); assertEquals(0, secureCache.size()); return null; } }); } @Test public void testWriterWrite() throws Exception { Subject writer = getWriterSubject(); Security.doAs(writer, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.put("test", "test value"); return null; } }); } @Test public void testWriterRemove() throws Exception { Subject writer = getWriterSubject(); Security.doAs(writer, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.remove(TEST_ENTRY_KEY); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testWriterRead() throws Exception { Subject writer = getWriterSubject(); Security.doAs(writer, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.get(TEST_ENTRY_KEY); return null; } }); } @Test public void testReaderRead() throws Exception { Subject reader = getReaderSubject(); Security.doAs(reader, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { assertEquals(TEST_ENTRY_VALUE, secureCache.get(TEST_ENTRY_KEY)); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testReaderWrite() throws Exception { Subject reader = getReaderSubject(); Security.doAs(reader, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.put("test", "test value"); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testReaderRemove() throws Exception { Subject reader = getReaderSubject(); Security.doAs(reader, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.remove(TEST_ENTRY_KEY); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testUnprivilegedRead() throws Exception { Subject unprivileged = getUnprivilegedSubject(); Security.doAs(unprivileged, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.get(TEST_ENTRY_KEY); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testUnprivilegedWrite() throws Exception { Subject unprivileged = getUnprivilegedSubject(); Security.doAs(unprivileged, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.put("test", "test value"); return null; } }); } @Test(expected = java.security.PrivilegedActionException.class) public void testUnprivilegedRemove() throws Exception { Subject unprivileged = getUnprivilegedSubject(); Security.doAs(unprivileged, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { secureCache.remove(TEST_ENTRY_KEY); return null; } }); } @Test(expected = java.lang.SecurityException.class) public void testUnauthenticatedRead() throws Exception { secureCache.get(TEST_ENTRY_KEY); } @Test(expected = java.lang.SecurityException.class) public void testUnauthenticatedWrite() throws Exception { secureCache.put("test", "value"); } @Test(expected = java.lang.SecurityException.class) public void testUnauthenticatedRemove() throws Exception { secureCache.remove(TEST_ENTRY_KEY); } }