This is an automated email from the ASF dual-hosted git repository.
brusdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/main by this push:
new c2bada6a77 ARTEMIS-4267 original exception lost for
NoCacheLoginException
c2bada6a77 is described below
commit c2bada6a770d9b0f6d19e5f3e137020c64954888
Author: Justin Bertram <[email protected]>
AuthorDate: Fri Apr 28 15:22:13 2023 -0500
ARTEMIS-4267 original exception lost for NoCacheLoginException
When skipping the authentication cache details for the original
exception are not logged.
This commit ensures these details are logged and adopts the
ExceptionUtils class from Apache Commons Lang in lieu of the previous
custom implementation.
---
.../activemq/artemis/utils/ExceptionUtil.java | 33 ----------
.../core/remoting/impl/netty/NettyAcceptor.java | 6 +-
.../core/security/impl/SecurityStoreImpl.java | 7 ++-
.../core/security/ActiveMQJAASSecurityManager.java | 19 ++----
.../core/security/ActiveMQSecurityManager5.java | 3 +-
.../spi/core/security/jaas/LDAPLoginModule.java | 10 ++--
.../core/security/jaas/NoCacheLoginException.java | 8 ++-
...va => JAASSecurityManagerClassLoadingTest.java} | 28 ++++-----
.../security/jaas/JAASSecurityManagerTest.java | 70 ++++------------------
.../core/security/jaas/NoCacheLoginModule.java | 56 +++++++++++++++++
artemis-server/src/test/resources/login.config | 6 +-
docs/user-manual/en/security.md | 15 +++--
.../jms/example/JAASSecurityManagerWrapper.java | 3 +-
.../tests/integration/security/SecurityTest.java | 2 +-
.../stomp/StompWithClientIdValidationTest.java | 3 +-
15 files changed, 127 insertions(+), 142 deletions(-)
diff --git
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ExceptionUtil.java
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ExceptionUtil.java
deleted file mode 100644
index e9f5073a31..0000000000
---
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ExceptionUtil.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.activemq.artemis.utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ExceptionUtil {
- public static Throwable getRootCause(final Throwable throwable) {
- List<Throwable> list = new ArrayList<>();
- Throwable current = throwable;
- while (current != null && list.contains(current) == false) {
- list.add(current);
- current = current.getCause();
- }
- return (list.size() < 2 ? throwable : list.get(list.size() - 1));
- }
-}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index a7ca627311..37cf6cfe9e 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -94,8 +94,8 @@ import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactoryProvider;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
-import org.apache.activemq.artemis.utils.ExceptionUtil;
import org.apache.activemq.artemis.utils.collections.TypedProperties;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -479,7 +479,7 @@ public class NettyAcceptor extends AbstractAcceptor {
pipeline.addLast("ssl", getSslHandler(channel.alloc(),
peerInfo.getA(), peerInfo.getB()));
pipeline.addLast("sslHandshakeExceptionHandler", new
SslHandshakeExceptionHandler());
} catch (Exception e) {
- Throwable rootCause = ExceptionUtil.getRootCause(e);
+ Throwable rootCause = ExceptionUtils.getRootCause(e);
ActiveMQServerLogger.LOGGER.gettingSslHandlerFailed(channel.remoteAddress().toString(),
rootCause.getClass().getName() + ": " + rootCause.getMessage());
logger.debug("Getting SSL handler failed", e);
@@ -1036,7 +1036,7 @@ public class NettyAcceptor extends AbstractAcceptor {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
if (cause.getMessage() != null &&
cause.getMessage().startsWith(SSLHandshakeException.class.getName())) {
- Throwable rootCause = ExceptionUtil.getRootCause(cause);
+ Throwable rootCause = ExceptionUtils.getRootCause(cause);
String errorMessage = rootCause.getClass().getName() + ": " +
rootCause.getMessage();
ActiveMQServerLogger.LOGGER.sslHandshakeFailed(ctx.channel().remoteAddress().toString(),
errorMessage);
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
index d4301be5cf..7f770d9711 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
@@ -189,7 +189,7 @@ public class SecurityStoreImpl implements SecurityStore,
HierarchicalRepositoryC
authenticationCache.put(createAuthenticationCacheKey(user,
password, connection), new Pair<>(subject != null, subject));
validatedUser = getUserFromSubject(subject);
} catch (NoCacheLoginException e) {
- logger.debug("Skipping authentication cache due to
exception", e);
+ handleNoCacheLoginException(e);
}
} else if (securityManager instanceof ActiveMQSecurityManager4) {
validatedUser = ((ActiveMQSecurityManager4)
securityManager).validateUser(user, password, connection, securityDomain);
@@ -413,12 +413,17 @@ public class SecurityStoreImpl implements SecurityStore,
HierarchicalRepositoryC
authenticationCache.put(createAuthenticationCacheKey(auth.getUsername(),
auth.getPassword(), auth.getRemotingConnection()), new Pair<>(subject != null,
subject));
return subject;
} catch (NoCacheLoginException e) {
+ handleNoCacheLoginException(e);
return null;
}
}
return cached.getB();
}
+ private void handleNoCacheLoginException(NoCacheLoginException e) {
+ logger.debug("Skipping authentication cache due to exception: {}",
e.getMessage());
+ }
+
// public for testing purposes
public void invalidateAuthorizationCache() {
authorizationCache.invalidateAll();
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
index bcfcc923bc..e73ebaa6af 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
@@ -19,6 +19,7 @@ package org.apache.activemq.artemis.spi.core.security;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
+import java.lang.invoke.MethodHandles;
import java.util.Set;
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
@@ -28,11 +29,9 @@ import
org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
import org.apache.activemq.artemis.spi.core.security.jaas.JaasCallbackHandler;
import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
import org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal;
-import org.apache.activemq.artemis.utils.ExceptionUtil;
import org.apache.activemq.artemis.utils.SecurityManagerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
import static
org.apache.activemq.artemis.core.remoting.CertificateUtil.getCertsFromConnection;
@@ -90,11 +89,14 @@ public class ActiveMQJAASSecurityManager implements
ActiveMQSecurityManager5 {
}
@Override
- public Subject authenticate(final String user, final String password,
RemotingConnection remotingConnection, final String securityDomain) {
+ public Subject authenticate(final String user, final String password,
RemotingConnection remotingConnection, final String securityDomain) throws
NoCacheLoginException {
try {
return getAuthenticatedSubject(user, password, remotingConnection,
securityDomain);
} catch (LoginException e) {
logger.debug("Couldn't validate user", e);
+ if (e instanceof NoCacheLoginException) {
+ throw (NoCacheLoginException) e;
+ }
return null;
}
}
@@ -138,16 +140,7 @@ public class ActiveMQJAASSecurityManager implements
ActiveMQSecurityManager5 {
} else {
lc = new LoginContext(configurationName, null, new
JaasCallbackHandler(user, password, remotingConnection), configuration);
}
- try {
- lc.login();
- } catch (LoginException e) {
- Throwable rootCause = ExceptionUtil.getRootCause(e);
- if (rootCause instanceof NoCacheLoginException) {
- throw (NoCacheLoginException) rootCause;
- } else {
- throw e;
- }
- }
+ lc.login();
return lc.getSubject();
} finally {
if (thisLoader != currentLoader) {
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager5.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager5.java
index f3871d01af..2af3459e2d 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager5.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager5.java
@@ -22,6 +22,7 @@ import java.util.Set;
import org.apache.activemq.artemis.core.security.CheckType;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
/**
* Used to validate whether a user is authorized to connect to the
@@ -44,7 +45,7 @@ public interface ActiveMQSecurityManager5 extends
ActiveMQSecurityManager {
* @param securityDomain the name of the JAAS security domain to use (can
be null)
* @return the Subject of the authenticated user, else null
*/
- Subject authenticate(String user, String password, RemotingConnection
remotingConnection, String securityDomain);
+ Subject authenticate(String user, String password, RemotingConnection
remotingConnection, String securityDomain) throws NoCacheLoginException;
/**
* Determine whether the given user has the correct role for the given
check type.
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
index 69d9b5a437..f8dc9692da 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
@@ -41,6 +41,7 @@ import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Principal;
@@ -59,11 +60,10 @@ import java.util.Queue;
import java.util.Set;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
-import org.apache.activemq.artemis.utils.ExceptionUtil;
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
public class LDAPLoginModule implements AuditLoginModule {
@@ -262,9 +262,9 @@ public class LDAPLoginModule implements AuditLoginModule {
}
private LoginException handleException(LoginException e) {
- Throwable t = ExceptionUtil.getRootCause(e);
- if (noCacheExceptions.contains(t.getClass().getName())) {
- t.initCause(new NoCacheLoginException());
+ 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);
}
return e;
}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/NoCacheLoginException.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/NoCacheLoginException.java
index 6db792f69a..3dea4c69fb 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/NoCacheLoginException.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/NoCacheLoginException.java
@@ -17,11 +17,13 @@
package org.apache.activemq.artemis.spi.core.security.jaas;
-public class NoCacheLoginException extends RuntimeException {
+import javax.security.auth.login.LoginException;
+
+public class NoCacheLoginException extends LoginException {
public NoCacheLoginException() {
super();
}
- public NoCacheLoginException(Exception e) {
- super(e);
+ public NoCacheLoginException(String message) {
+ super(message);
}
}
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerClassLoadingTest.java
similarity index 98%
copy from
artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
copy to
artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerClassLoadingTest.java
index c8ded103c9..0482d1d37b 100644
---
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerClassLoadingTest.java
@@ -17,36 +17,35 @@
package org.apache.activemq.artemis.core.security.jaas;
import javax.security.auth.Subject;
+import java.io.UnsupportedEncodingException;
+import java.lang.invoke.MethodHandles;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.activemq.artemis.core.security.CheckType;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl;
import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@RunWith(Parameterized.class)
-public class JAASSecurityManagerTest {
+public class JAASSecurityManagerClassLoadingTest {
private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Parameterized.Parameters(name = "newLoader=({0})")
@@ -102,5 +101,4 @@ public class JAASSecurityManagerTest {
Thread.currentThread().setContextClassLoader(existingLoader);
}
}
-
}
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
index c8ded103c9..b37bdc1aa0 100644
---
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/JAASSecurityManagerTest.java
@@ -16,43 +16,19 @@
*/
package org.apache.activemq.artemis.core.security.jaas;
-import javax.security.auth.Subject;
-
-import org.apache.activemq.artemis.core.security.CheckType;
-import org.apache.activemq.artemis.core.security.Role;
-import org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl;
-import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
import java.io.UnsupportedEncodingException;
import java.net.URL;
-import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+
+import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
+import org.junit.Test;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-@RunWith(Parameterized.class)
public class JAASSecurityManagerTest {
- private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- @Parameterized.Parameters(name = "newLoader=({0})")
- public static Collection<Object[]> data() {
- return Arrays.asList(new Object[][] {{true}, {false}});
- }
static {
String path = System.getProperty("java.security.auth.login.config");
@@ -69,38 +45,14 @@ public class JAASSecurityManagerTest {
}
}
- @Parameterized.Parameter
- public boolean usingNewLoader;
-
- @Rule
- public TemporaryFolder tmpDir = new TemporaryFolder();
-
@Test
- public void testLoginClassloading() throws Exception {
- ClassLoader existingLoader =
Thread.currentThread().getContextClassLoader();
- logger.debug("loader: {}", existingLoader);
+ public void testNoCacheLoginException() {
+ ActiveMQJAASSecurityManager securityManager = new
ActiveMQJAASSecurityManager("testNoCacheLoginException");
try {
- if (usingNewLoader) {
- URLClassLoader simulatedLoader = new URLClassLoader(new
URL[]{tmpDir.getRoot().toURI().toURL()}, null);
- Thread.currentThread().setContextClassLoader(simulatedLoader);
- }
- ActiveMQJAASSecurityManager securityManager = new
ActiveMQJAASSecurityManager("PropertiesLogin");
-
- Subject result = securityManager.authenticate("first", "secret",
null, null);
-
- assertNotNull(result);
- assertEquals("first", SecurityStoreImpl.getUserFromSubject(result));
-
- Role role = new Role("programmers", true, true, true, true, true,
true, true, true, true, true);
- Set<Role> roles = new HashSet<>();
- roles.add(role);
- boolean authorizationResult = securityManager.authorize(result,
roles, CheckType.SEND, "someaddress");
-
- assertTrue(authorizationResult);
-
- } finally {
- Thread.currentThread().setContextClassLoader(existingLoader);
+ securityManager.authenticate(null, null, null, null);
+ fail();
+ } catch (NoCacheLoginException ncle) {
+ assertEquals(NoCacheLoginModule.MESSAGE, ncle.getMessage());
}
}
-
}
diff --git
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/NoCacheLoginModule.java
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/NoCacheLoginModule.java
new file mode 100644
index 0000000000..536ee305bc
--- /dev/null
+++
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/jaas/NoCacheLoginModule.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.activemq.artemis.core.security.jaas;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.util.Map;
+
+import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
+import org.apache.activemq.artemis.utils.RandomUtil;
+
+public class NoCacheLoginModule implements LoginModule {
+ public static final String MESSAGE = RandomUtil.randomString();
+
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> map, Map<String, ?> map1) {
+ }
+
+ @Override
+ public boolean login() throws LoginException {
+ throw (NoCacheLoginException) new
NoCacheLoginException(MESSAGE).initCause(new FailedLoginException());
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ return false;
+ }
+
+ @Override
+ public boolean abort() throws LoginException {
+ return false;
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ return false;
+ }
+}
diff --git a/artemis-server/src/test/resources/login.config
b/artemis-server/src/test/resources/login.config
index 106919bf41..ad1fa34cf2 100644
--- a/artemis-server/src/test/resources/login.config
+++ b/artemis-server/src/test/resources/login.config
@@ -237,4 +237,8 @@ HttpServerAuthenticator {
org.apache.activemq.artemis.spi.core.security.jaas.KubernetesLoginModule
sufficient
debug=true
org.apache.activemq.jaas.kubernetes.role="cert-roles.properties";
-};
\ No newline at end of file
+};
+
+testNoCacheLoginException {
+ org.apache.activemq.artemis.core.security.jaas.NoCacheLoginModule required;
+};
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 004b6deafc..df66ea4a25 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -835,13 +835,18 @@ system. It is implemented by
because it has no default value. Example value: `(member={0})`.
- `noCacheExceptions` - comma separated list of class names of exceptions
which
- may thrown during communication with the LDAP server; default is empty.
+ 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. However, in cases where the failure is, for example, due to a
temporary
- network outage and the `security-invalidation-interval` is relatively high
this
- can be problematic. Users can enumerate any relevant exceptions which the
cache
- should ignore (e.g. `java.net.ConnectException`) to avoid any such problems.
+ 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
+ the configured exceptions are being skipped by enabling debug logging for
+ `org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl`.
- `debug` - boolean flag; if `true`, enable debugging; this is used only for
testing or debugging; normally, it should be set to `false`, or omitted;
diff --git
a/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
index 132c55ff11..ef6e402ae2 100644
---
a/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
+++
b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
@@ -26,12 +26,13 @@ import
org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager5;
+import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
public class JAASSecurityManagerWrapper implements ActiveMQSecurityManager5 {
ActiveMQJAASSecurityManager activeMQJAASSecurityManager;
@Override
- public Subject authenticate(String user, String password,
RemotingConnection remotingConnection, String securityDomain) {
+ public Subject authenticate(String user, String password,
RemotingConnection remotingConnection, String securityDomain) throws
NoCacheLoginException {
System.out.println("authenticate(" + user + ", " + password + ", " +
remotingConnection.getRemoteAddress() + ", " + securityDomain + ")");
return activeMQJAASSecurityManager.authenticate(user, password,
remotingConnection, securityDomain);
}
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
index 2507971d7e..1b34dd3281 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
@@ -142,7 +142,7 @@ public class SecurityTest extends ActiveMQTestBase {
public Subject authenticate(String user,
String password,
RemotingConnection remotingConnection,
- String securityDomain) {
+ String securityDomain) throws
NoCacheLoginException {
flipper = !flipper;
if (flipper) {
return new Subject();
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompWithClientIdValidationTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompWithClientIdValidationTest.java
index 070d87cecd..261f475599 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompWithClientIdValidationTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompWithClientIdValidationTest.java
@@ -29,6 +29,7 @@ import
org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
import
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
+import
org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
import
org.apache.activemq.artemis.tests.integration.stomp.util.StompClientConnection;
import
org.apache.activemq.artemis.tests.integration.stomp.util.StompClientConnectionFactory;
import org.junit.Test;
@@ -52,7 +53,7 @@ public class StompWithClientIdValidationTest extends
StompTestBase {
ActiveMQJAASSecurityManager securityManager = new
ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), new
SecurityConfiguration()) {
@Override
- public Subject authenticate(String user, String password,
RemotingConnection remotingConnection, String securityDomain) {
+ public Subject authenticate(String user, String password,
RemotingConnection remotingConnection, String securityDomain) throws
NoCacheLoginException {
Subject validatedUser = super.authenticate(user, password,
remotingConnection, securityDomain);
if (validatedUser == null) {