ARTEMIS-4297 allow regex in no-cache exception config

This commit is contained in:
Justin Bertram 2023-05-31 10:57:13 -05:00 committed by clebertsuconic
parent 40425d422a
commit e7de2c7001
4 changed files with 79 additions and 13 deletions

View File

@ -58,6 +58,7 @@ import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
@ -263,12 +264,26 @@ public class LDAPLoginModule implements AuditLoginModule {
private LoginException handleException(LoginException e) {
Throwable rootCause = ExceptionUtils.getRootCause(e);
if (noCacheExceptions.contains(rootCause.getClass().getName())) {
return (NoCacheLoginException) new NoCacheLoginException(rootCause.getClass().getName() + (rootCause.getMessage() == null ? "" : ": " + rootCause.getMessage())).initCause(e);
String rootCauseClass = rootCause.getClass().getName();
// try to match statically first
if (noCacheExceptions.contains(rootCauseClass)) {
return getNoCacheLoginException(e, rootCause);
} else {
// if no static matches are found try regex
for (String match : noCacheExceptions) {
if (Pattern.matches(match, rootCauseClass)) {
return getNoCacheLoginException(e, rootCause);
}
}
}
return e;
}
private NoCacheLoginException getNoCacheLoginException(LoginException e, Throwable rootCause) {
return (NoCacheLoginException) new NoCacheLoginException(rootCause.getClass().getName() + (rootCause.getMessage() == null ? "" : ": " + rootCause.getMessage())).initCause(e);
}
private void clear() {
username = null;
userAuthenticated = false;

View File

@ -834,17 +834,18 @@ system. It is implemented by
previous role search. This option must always be set to enable role expansion
because it has no default value. Example value: `(member={0})`.
- `noCacheExceptions` - comma separated list of class names of exceptions which
may be thrown during communication with the LDAP server; default is empty.
Typically any failure to authenticate will be stored in the authentication cache
so that the underlying security data store (e.g. LDAP) is spared any unnecessary
traffic. For example, an application with the wrong password attempting to login
multiple times in short order might adversely impact the LDAP server. However, in
cases where the failure is, for example, due to a temporary network outage and
the `security-invalidation-interval` is relatively high then _not_ caching such
failures would be better. Users can enumerate any relevant exceptions which the
cache should ignore (e.g. `java.net.ConnectException`). The name of the exception
should be the **root cause** from the relevant stack-trace. Users can confirm
- `noCacheExceptions` - comma separated list of class names or regular expressions
to match exceptions which may be thrown during communication with the LDAP
server; default is empty. Typically any failure to authenticate will be stored in
the authentication cache so that the underlying security data store (e.g. LDAP)
is spared any unnecessary traffic. For example, an application with the wrong
password attempting to login multiple times in short order might adversely impact
the LDAP server. However, in cases where the failure is, for example, due to a
temporary network outage and the `security-invalidation-interval` is relatively
high then _not_ caching such failures would be better. Users can enumerate any
relevant exceptions which the cache should ignore (e.g.
`java.net.ConnectException`). The name of the exception or the regular expression
should match the **root cause** from the relevant stack-trace. Users can confirm
the configured exceptions are being skipped by enabling debug logging for
`org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl`.

View File

@ -185,11 +185,21 @@ public class SecurityTest extends ActiveMQTestBase {
internalTestNoCacheException("BrokenLDAPLoginNamingException");
}
@Test
public void testNoCacheNamingExceptionRegex() throws Exception {
internalTestNoCacheException("BrokenLDAPLoginNamingExceptionRegex");
}
@Test
public void testNoCacheConnectException() throws Exception {
internalTestNoCacheException("BrokenLDAPLoginConnectException");
}
@Test
public void testNoCacheConnectExceptionRegex() throws Exception {
internalTestNoCacheException("BrokenLDAPLoginConnectExceptionRegex");
}
private void internalTestNoCacheException(String ldapConfigName) throws Exception {
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager(ldapConfigName);
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));

View File

@ -106,6 +106,26 @@ BrokenLDAPLoginNamingException {
;
};
BrokenLDAPLoginNamingExceptionRegex {
org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:1024"
connectionUsername="uid=admin,ou=system"
connectionPassword=""
connectionProtocol=s
authentication=simple
userBase="ou=system"
userSearchMatching="(uid={0})"
userSearchSubtree=false
roleBase="ou=system"
roleName=dummyRoleName
roleSearchMatching="(uid={1})"
roleSearchSubtree=false
noCacheExceptions=".*\\..*\\.NamingException"
;
};
BrokenLDAPLoginConnectException {
org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
debug=true
@ -126,6 +146,26 @@ BrokenLDAPLoginConnectException {
;
};
BrokenLDAPLoginConnectExceptionRegex {
org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:1024"
connectionUsername="uid=admin,ou=system"
connectionPassword="123"
connectionProtocol=s
authentication=simple
userBase="ou=system"
userSearchMatching="(uid={0})"
userSearchSubtree=false
roleBase="ou=system"
roleName=dummyRoleName
roleSearchMatching="(uid={1})"
roleSearchSubtree=false
noCacheExceptions="nomatch, .*"
;
};
ExpandedLDAPLogin {
org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
debug=true