mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3845 - handle LDAP restarts in cached ldap authorization map
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1348761 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
21a0465448
commit
06949a5074
|
@ -94,6 +94,22 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
protected HashMap<ActiveMQDestination, AuthorizationEntry> entries =
|
protected HashMap<ActiveMQDestination, AuthorizationEntry> entries =
|
||||||
new HashMap<ActiveMQDestination, AuthorizationEntry>();
|
new HashMap<ActiveMQDestination, AuthorizationEntry>();
|
||||||
|
|
||||||
|
protected DirContext createContext() throws NamingException {
|
||||||
|
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
|
||||||
|
if (connectionUsername != null || !"".equals(connectionUsername)) {
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
|
||||||
|
}
|
||||||
|
if (connectionPassword != null || !"".equals(connectionPassword)) {
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
|
||||||
|
}
|
||||||
|
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
|
||||||
|
env.put(Context.PROVIDER_URL, connectionURL);
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, authentication);
|
||||||
|
//env.put("com.sun.jndi.ldap.connect.pool", "true");
|
||||||
|
return new InitialDirContext(env);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the existing open context or creates a new one and registers listeners for
|
* Returns the existing open context or creates a new one and registers listeners for
|
||||||
* push notifications if such an update style is enabled. This implementation should not
|
* push notifications if such an update style is enabled. This implementation should not
|
||||||
|
@ -105,23 +121,20 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
*/
|
*/
|
||||||
protected DirContext open() throws NamingException {
|
protected DirContext open() throws NamingException {
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
return context;
|
boolean alive = true;
|
||||||
|
try {
|
||||||
|
context.getAttributes("");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.info("LDAP connection failed", e);
|
||||||
|
alive = false;
|
||||||
|
}
|
||||||
|
if (alive) {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
context = createContext();
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
|
|
||||||
if (connectionUsername != null || !"".equals(connectionUsername)) {
|
|
||||||
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
|
|
||||||
}
|
|
||||||
if (connectionPassword != null || !"".equals(connectionPassword)) {
|
|
||||||
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
|
|
||||||
}
|
|
||||||
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
|
|
||||||
env.put(Context.PROVIDER_URL, connectionURL);
|
|
||||||
env.put(Context.SECURITY_AUTHENTICATION, authentication);
|
|
||||||
context = new InitialDirContext(env);
|
|
||||||
|
|
||||||
|
|
||||||
if (refreshInterval == -1 && !refreshDisabled) {
|
if (refreshInterval == -1 && !refreshDisabled) {
|
||||||
eventContext = ((EventDirContext)context.lookup(""));
|
eventContext = ((EventDirContext)context.lookup(""));
|
||||||
|
@ -158,6 +171,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
eventContext.addNamingListener(tempSearchBase, getFilterForPermissionType(permissionType), constraints,
|
eventContext.addNamingListener(tempSearchBase, getFilterForPermissionType(permissionType), constraints,
|
||||||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.TEMP, permissionType));
|
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.TEMP, permissionType));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (NamingException e) {
|
} catch (NamingException e) {
|
||||||
context = null;
|
context = null;
|
||||||
|
@ -616,8 +630,15 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
* and are the refresh interval has elapsed.
|
* and are the refresh interval has elapsed.
|
||||||
*/
|
*/
|
||||||
protected void checkForUpdates() {
|
protected void checkForUpdates() {
|
||||||
if (!refreshDisabled && (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval)) {
|
if (context == null || (!refreshDisabled && (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval))) {
|
||||||
|
if (context == null) {
|
||||||
|
try {
|
||||||
|
context = createContext();
|
||||||
|
} catch (NamingException ne) {
|
||||||
|
// LDAP is down, use already cached values
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
reset();
|
reset();
|
||||||
setTempDestinationAuthorizationEntry(null);
|
setTempDestinationAuthorizationEntry(null);
|
||||||
entries.clear();
|
entries.clear();
|
||||||
|
@ -688,6 +709,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||||
*/
|
*/
|
||||||
public synchronized Set<Object> getReadACLs(ActiveMQDestination destination) {
|
public synchronized Set<Object> getReadACLs(ActiveMQDestination destination) {
|
||||||
|
checkForUpdates();
|
||||||
return super.getReadACLs(destination);
|
return super.getReadACLs(destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,6 +718,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||||
*/
|
*/
|
||||||
public synchronized Set<Object> getWriteACLs(ActiveMQDestination destination) {
|
public synchronized Set<Object> getWriteACLs(ActiveMQDestination destination) {
|
||||||
|
checkForUpdates();
|
||||||
return super.getWriteACLs(destination);
|
return super.getWriteACLs(destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,6 +873,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
||||||
* @param namingExceptionEvent the exception event
|
* @param namingExceptionEvent the exception event
|
||||||
*/
|
*/
|
||||||
public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
|
public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
|
||||||
|
context = null;
|
||||||
LOG.error("Caught unexpected exception.", namingExceptionEvent.getException());
|
LOG.error("Caught unexpected exception.", namingExceptionEvent.getException());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,53 @@ public abstract class AbstractCachedLDAPAuthorizationMapLegacyTest extends Abstr
|
||||||
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||||
assertEquals("set size: " + failedACLs, 1, failedACLs.size());
|
assertEquals("set size: " + failedACLs, 1, failedACLs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRestartAsync() throws Exception {
|
||||||
|
testRestart(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRestartSync() throws Exception {
|
||||||
|
testRestart(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRestart(boolean sync) throws Exception {
|
||||||
|
map.query();
|
||||||
|
if (sync) {
|
||||||
|
map.setRefreshInterval(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<?> failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
|
||||||
|
assertEquals("set size: " + failedACLs, 0, failedACLs.size());
|
||||||
|
|
||||||
|
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||||
|
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||||
|
|
||||||
|
getLdapServer().stop();
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||||
|
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||||
|
|
||||||
|
getLdapServer().start();
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
connection = getLdapConnection();
|
||||||
|
|
||||||
|
LdifReader reader = new LdifReader(getAddLdif());
|
||||||
|
|
||||||
|
for (LdifEntry entry : reader) {
|
||||||
|
connection.add(entry.getEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(2000);
|
||||||
|
|
||||||
|
failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
|
||||||
|
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||||
|
}
|
||||||
|
|
||||||
protected CachedLDAPAuthorizationMap createMap() {
|
protected CachedLDAPAuthorizationMap createMap() {
|
||||||
return new CachedLDAPAuthorizationMap();
|
return new CachedLDAPAuthorizationMap();
|
||||||
|
|
Loading…
Reference in New Issue