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.
This commit is contained in:
parent
5e32a1ab62
commit
c2bada6a77
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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 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.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
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 JAASSecurityManagerClassLoadingTest {
|
||||
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");
|
||||
if (path == null) {
|
||||
URL resource = PropertiesLoginModuleTest.class.getClassLoader().getResource("login.config");
|
||||
if (resource != null) {
|
||||
try {
|
||||
path = URLDecoder.decode(resource.getFile(), StandardCharsets.UTF_8.name());
|
||||
System.setProperty("java.security.auth.login.config", path);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
testNoCacheLoginException {
|
||||
org.apache.activemq.artemis.core.security.jaas.NoCacheLoginModule required;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue