Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import org.apache.activemq.broker.region.Destination;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ConnectionInfo;
import org.apache.activemq.security.AbstractAuthenticationBroker;
import org.apache.activemq.security.AuthorizationBroker;
import org.apache.activemq.security.AuthorizationMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -169,4 +172,24 @@ protected String filterPasswords(Object toEscape) {
return matchPassword.matcher(toEscape.toString()).replaceAll("password=???,");
}

}
protected void updateAuthorizationMap(final AuthorizationMap authorizationMap) {
try {
// replace authorization map - need exclusive write lock to total broker
AuthorizationBroker authorizationBroker =
(AuthorizationBroker) getBrokerService().getBroker().getAdaptor(AuthorizationBroker.class);

authorizationBroker.setAuthorizationMap(authorizationMap);

AbstractAuthenticationBroker authenticationBroker =
(AbstractAuthenticationBroker) getBrokerService().getBroker().getAdaptor(
AbstractAuthenticationBroker.class);

// clear producer authorizedWriteDests cache for each SecurityContext
if (authenticationBroker != null) {
authenticationBroker.refresh();
}
} catch (Exception e) {
info("failed to apply modified AuthorizationMap to AuthorizationBroker", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,7 @@ public AuthorizationPluginProcessor(RuntimeConfigurationBroker plugin, Class con

@Override
public void modify(Object existing, Object candidate) {
try {
// replace authorization map - need exclusive write lock to total broker
AuthorizationBroker authorizationBroker =
(AuthorizationBroker) plugin.getBrokerService().getBroker().getAdaptor(AuthorizationBroker.class);

authorizationBroker.setAuthorizationMap(fromDto(filter(candidate, DtoAuthorizationPlugin.Map.class)));
} catch (Exception e) {
plugin.info("failed to apply modified AuthorizationMap to AuthorizationBroker", e);
}
plugin.updateAuthorizationMap(fromDto(filter(candidate, DtoAuthorizationPlugin.Map.class)));
}

private AuthorizationMap fromDto(List<Object> map) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.activemq.plugin.AbstractRuntimeConfigurationBroker;
import org.apache.activemq.plugin.UpdateVirtualDestinationsTask;
import org.apache.activemq.plugin.util.PolicyEntryUtil;
import org.apache.activemq.security.AbstractAuthenticationBroker;
import org.apache.activemq.security.AuthorizationBroker;
import org.apache.activemq.security.AuthorizationMap;
import org.apache.activemq.security.SimpleAuthenticationBroker;
Expand Down Expand Up @@ -235,16 +236,8 @@ public void run() {
}
}

//authorization map
@Override
public void updateAuthorizationMap(final AuthorizationMap authorizationMap) {
try {
// replace authorization map - need exclusive write lock to total broker
AuthorizationBroker authorizationBroker =
(AuthorizationBroker) getBrokerService().getBroker().getAdaptor(AuthorizationBroker.class);

authorizationBroker.setAuthorizationMap(authorizationMap);
} catch (Exception e) {
info("failed to apply modified AuthorizationMap to AuthorizationBroker", e);
}
super.updateAuthorizationMap(authorizationMap);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@
*/
package org.apache.activemq;

import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import jakarta.jms.Connection;
import jakarta.jms.JMSSecurityException;
import jakarta.jms.MessageProducer;
import jakarta.jms.Session;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.security.DefaultAuthorizationMap;
import org.junit.Test;

public class AuthorizationTest extends AbstractAuthorizationTest {
Expand Down Expand Up @@ -82,6 +90,84 @@ public void testModAddWrite() throws Exception {
assertAllowedWrite("guest", "USERS.A");
}

@Test
public void testModAddExistingProducer() throws Exception {
final String brokerConfig = configurationSeed + "-auth-broker";
applyNewConfig(brokerConfig, configurationSeed + "-users");
startBroker(brokerConfig);
assertTrue("broker alive", brokerService.isStarted());

try (Connection connection = new ActiveMQConnectionFactory("vm://localhost")
.createConnection("user", "user")) {
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer userProd
= session.createProducer(session.createQueue("USERS.A"));
// can only create an anonymous, normal producer is denied for GUESTS.A
MessageProducer anonProd
= session.createProducer(null);

// allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());

// denied
// producer should be denied
assertDenied("user", "GUESTS.A");
assertThrows(JMSSecurityException.class, () -> anonProd.send(
session.createQueue("GUESTS.A"), session.createTextMessage()));

applyNewConfig(brokerConfig, configurationSeed + "-users-guests", WAIT_FOR_CHANGE);

// all allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());
// must create new producer, previous was not allowed
assertAllowedWrite("user", "GUESTS.A");
anonProd.send(session.createQueue("GUESTS.A"), session.createTextMessage());
}
}

@Test
public void testModRmExistingProducer() throws Exception {
final String brokerConfig = configurationSeed + "-auth-rm-broker";
applyNewConfig(brokerConfig, configurationSeed + "-users-guests");
startBroker(brokerConfig);
assertTrue("broker alive", brokerService.isStarted());


try (Connection connection = new ActiveMQConnectionFactory("vm://localhost")
.createConnection("user", "user")) {
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer userProd
= session.createProducer(session.createQueue("USERS.A"));
MessageProducer guestProd
= session.createProducer(session.createQueue("GUESTS.A"));
MessageProducer anonProd
= session.createProducer(null);

// all allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());
guestProd.send(session.createTextMessage());
anonProd.send(session.createQueue("GUESTS.A"), session.createTextMessage());

applyNewConfig(brokerConfig, configurationSeed + "-users", WAIT_FOR_CHANGE);

// still allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());

// now denied
assertThrows(JMSSecurityException.class, () -> guestProd.send(session.createTextMessage()));
assertThrows(JMSSecurityException.class, () -> anonProd.send(
session.createQueue("GUESTS.A"), session.createTextMessage()));
}
}

@Test
public void testModWithGroupClass() throws Exception {
final String brokerConfig = configurationSeed + "-auth-add-guest-broker";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
*/
package org.apache.activemq.java;

import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import jakarta.jms.Connection;
import jakarta.jms.JMSSecurityException;
import jakarta.jms.MessageProducer;
import jakarta.jms.Session;
import java.util.ArrayList;
import java.util.List;

import java.util.concurrent.TimeUnit;
import org.apache.activemq.AbstractAuthorizationTest;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerPlugin;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.filter.DestinationMapEntry;
Expand Down Expand Up @@ -95,6 +102,8 @@ public void testModRm() throws Exception {
javaConfigBroker.updateAuthorizationMap(authorizationMap);
assertAllowed("user", "USERS.A");
assertAllowed("guest", "GUESTS.A");
assertAllowedWrite("user", "USERS.A");
assertAllowedWrite("user", "GUESTS.A");
assertDenied("user", "GUESTS.A");
assertAllowedTemp("guest");

Expand All @@ -103,9 +112,97 @@ public void testModRm() throws Exception {

assertAllowed("user", "USERS.A");
assertDenied("user", "GUESTS.A");
assertDeniedWrite("user", "GUESTS.A");
assertDeniedTemp("guest");
}

@Test
public void testModRmExistingProducer() throws Exception {
DefaultAuthorizationMap authorizationMap = buildUsersGuestsMap();
BrokerService brokerService = new BrokerService();
startBroker(brokerService);
assertTrue("broker alive", brokerService.isStarted());

javaConfigBroker.updateAuthorizationMap(authorizationMap);
TimeUnit.SECONDS.sleep(SLEEP);

try (Connection connection = new ActiveMQConnectionFactory("vm://localhost")
.createConnection("user", "user")) {
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer userProd
= session.createProducer(session.createQueue("USERS.A"));
MessageProducer guestProd
= session.createProducer(session.createQueue("GUESTS.A"));
MessageProducer anonProd
= session.createProducer(null);

// all allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());
guestProd.send(session.createTextMessage());
anonProd.send(session.createQueue("GUESTS.A"), session.createTextMessage());

authorizationMap = buildUsersMap();
javaConfigBroker.updateAuthorizationMap(authorizationMap);
TimeUnit.SECONDS.sleep(SLEEP);

// still allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());

// now denied
assertThrows(JMSSecurityException.class, () -> guestProd.send(session.createTextMessage()));
assertThrows(JMSSecurityException.class, () -> anonProd.send(
session.createQueue("GUESTS.A"), session.createTextMessage()));
}
}

@Test
public void testModAddExistingProducer() throws Exception {
DefaultAuthorizationMap authorizationMap = buildUsersMap();
BrokerService brokerService = new BrokerService();
startBroker(brokerService);
assertTrue("broker alive", brokerService.isStarted());

javaConfigBroker.updateAuthorizationMap(authorizationMap);
TimeUnit.SECONDS.sleep(SLEEP);

try (Connection connection = new ActiveMQConnectionFactory("vm://localhost")
.createConnection("user", "user")) {
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer userProd
= session.createProducer(session.createQueue("USERS.A"));
// can only create an anonymous, normal producer is denied for GUESTS.A
MessageProducer anonProd
= session.createProducer(null);

// allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());

// denied
// producer should be denied
assertDenied("user", "GUESTS.A");
assertThrows(JMSSecurityException.class, () -> anonProd.send(
session.createQueue("GUESTS.A"), session.createTextMessage()));

authorizationMap = buildUsersGuestsMap();
javaConfigBroker.updateAuthorizationMap(authorizationMap);
TimeUnit.SECONDS.sleep(SLEEP);

// all allowed
userProd.send(session.createTextMessage());
anonProd.send(session.createQueue("USERS.A"), session.createTextMessage());
// must create new producer, previous was not allowed
assertAllowedWrite("user", "GUESTS.A");
anonProd.send(session.createQueue("GUESTS.A"), session.createTextMessage());
}
}

@Test
public void testWildcard() throws Exception {
DefaultAuthorizationMap authorizationMap = buildWildcardUsersGuestsMap();
Expand Down
Loading