https://issues.apache.org/jira/browse/ARTEMIS-537 - allow artemis to work properly with karaf jaas implementation
This commit is contained in:
parent
4a11a631bc
commit
5db163753d
|
@ -65,14 +65,14 @@ under the License.
|
||||||
|
|
||||||
<security-settings>
|
<security-settings>
|
||||||
<security-setting match="#">
|
<security-setting match="#">
|
||||||
<permission type="createNonDurableQueue" roles="amq"/>
|
<permission type="createNonDurableQueue" roles="manager"/>
|
||||||
<permission type="deleteNonDurableQueue" roles="amq"/>
|
<permission type="deleteNonDurableQueue" roles="manager"/>
|
||||||
<permission type="createDurableQueue" roles="amq"/>
|
<permission type="createDurableQueue" roles="manager"/>
|
||||||
<permission type="deleteDurableQueue" roles="amq"/>
|
<permission type="deleteDurableQueue" roles="manager"/>
|
||||||
<permission type="consume" roles="amq"/>
|
<permission type="consume" roles="manager"/>
|
||||||
<permission type="send" roles="amq"/>
|
<permission type="send" roles="manager"/>
|
||||||
<!-- we need this otherwise ./artemis data imp wouldn't work -->
|
<!-- we need this otherwise ./artemis data imp wouldn't work -->
|
||||||
<permission type="manage" roles="amq"/>
|
<permission type="manage" roles="manager"/>
|
||||||
</security-setting>
|
</security-setting>
|
||||||
</security-settings>
|
</security-settings>
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ under the License.
|
||||||
<max-size-bytes>10485760</max-size-bytes>
|
<max-size-bytes>10485760</max-size-bytes>
|
||||||
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
||||||
<address-full-policy>BLOCK</address-full-policy>
|
<address-full-policy>BLOCK</address-full-policy>
|
||||||
|
<auto-create-jms-queues>true</auto-create-jms-queues>
|
||||||
</address-setting>
|
</address-setting>
|
||||||
</address-settings>
|
</address-settings>
|
||||||
</core>
|
</core>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
config=file:etc/artemis.xml
|
config=file:etc/artemis.xml
|
||||||
name=local
|
name=local
|
||||||
domain=local
|
domain=karaf
|
||||||
|
rolePrincipalClass=org.apache.karaf.jaas.boot.principal.RolePrincipal
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.osgi.util.tracker.ServiceTracker;
|
||||||
public class OsgiBroker {
|
public class OsgiBroker {
|
||||||
private String name;
|
private String name;
|
||||||
private String configurationUrl;
|
private String configurationUrl;
|
||||||
|
private String rolePrincipalClass;
|
||||||
private Map<String, ActiveMQComponent> components;
|
private Map<String, ActiveMQComponent> components;
|
||||||
private Map<String, ServiceRegistration<?>> registrations;
|
private Map<String, ServiceRegistration<?>> registrations;
|
||||||
private ServiceTracker tracker;
|
private ServiceTracker tracker;
|
||||||
|
@ -60,8 +61,12 @@ public class OsgiBroker {
|
||||||
final Dictionary<String, Object> properties = cctx.getProperties();
|
final Dictionary<String, Object> properties = cctx.getProperties();
|
||||||
configurationUrl = getMandatory(properties, "config");
|
configurationUrl = getMandatory(properties, "config");
|
||||||
name = getMandatory(properties, "name");
|
name = getMandatory(properties, "name");
|
||||||
|
rolePrincipalClass = (String)properties.get("rolePrincipalClass");
|
||||||
String domain = getMandatory(properties, "domain");
|
String domain = getMandatory(properties, "domain");
|
||||||
ActiveMQJAASSecurityManager security = new ActiveMQJAASSecurityManager(domain);
|
ActiveMQJAASSecurityManager security = new ActiveMQJAASSecurityManager(domain);
|
||||||
|
if (rolePrincipalClass != null) {
|
||||||
|
security.setRolePrincipalClass(rolePrincipalClass);
|
||||||
|
}
|
||||||
String brokerInstance = null;
|
String brokerInstance = null;
|
||||||
String karafDataDir = System.getProperty("karaf.data");
|
String karafDataDir = System.getProperty("karaf.data");
|
||||||
if (karafDataDir != null) {
|
if (karafDataDir != null) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import javax.security.auth.Subject;
|
||||||
import javax.security.auth.login.LoginContext;
|
import javax.security.auth.login.LoginContext;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.cert.X509Certificate;
|
import javax.security.cert.X509Certificate;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -45,8 +47,11 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ActiveMQJAASSecurityManager.class);
|
private static final Logger logger = Logger.getLogger(ActiveMQJAASSecurityManager.class);
|
||||||
|
|
||||||
|
private static final String WILDCARD = "*";
|
||||||
|
|
||||||
private String configurationName;
|
private String configurationName;
|
||||||
private SecurityConfiguration configuration;
|
private SecurityConfiguration configuration;
|
||||||
|
private String rolePrincipalClass = "org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal";
|
||||||
|
|
||||||
public ActiveMQJAASSecurityManager() {
|
public ActiveMQJAASSecurityManager() {
|
||||||
}
|
}
|
||||||
|
@ -72,7 +77,10 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (LoginException e) {
|
catch (LoginException e) {
|
||||||
logger.debug("Couldn't validate user", e);
|
logger.info("Couldn't validate user: " + e.getMessage());
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Couldn't validate user", e);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,9 +116,15 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
|
||||||
Set<RolePrincipal> rolesWithPermission = getPrincipalsInRole(checkType, roles);
|
Set<RolePrincipal> rolesWithPermission = getPrincipalsInRole(checkType, roles);
|
||||||
|
|
||||||
// Check the caller's roles
|
// Check the caller's roles
|
||||||
Set<RolePrincipal> rolesForSubject = localSubject.getPrincipals(RolePrincipal.class);
|
Set<Principal> rolesForSubject = new HashSet<Principal>();
|
||||||
|
try {
|
||||||
|
rolesForSubject.addAll(localSubject.getPrincipals(Class.forName(rolePrincipalClass).asSubclass(Principal.class)));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
logger.info("Can't find roles for the subject", e);
|
||||||
|
}
|
||||||
if (rolesForSubject.size() > 0 && rolesWithPermission.size() > 0) {
|
if (rolesForSubject.size() > 0 && rolesWithPermission.size() > 0) {
|
||||||
Iterator<RolePrincipal> rolesForSubjectIter = rolesForSubject.iterator();
|
Iterator<Principal> rolesForSubjectIter = rolesForSubject.iterator();
|
||||||
while (!authorized && rolesForSubjectIter.hasNext()) {
|
while (!authorized && rolesForSubjectIter.hasNext()) {
|
||||||
Iterator<RolePrincipal> rolesWithPermissionIter = rolesWithPermission.iterator();
|
Iterator<RolePrincipal> rolesWithPermissionIter = rolesWithPermission.iterator();
|
||||||
Principal subjectRole = rolesForSubjectIter.next();
|
Principal subjectRole = rolesForSubjectIter.next();
|
||||||
|
@ -136,10 +150,15 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<RolePrincipal> getPrincipalsInRole(final CheckType checkType, final Set<Role> roles) {
|
private Set<RolePrincipal> getPrincipalsInRole(final CheckType checkType, final Set<Role> roles) {
|
||||||
Set<RolePrincipal> principals = new HashSet<>();
|
Set principals = new HashSet<>();
|
||||||
for (Role role : roles) {
|
for (Role role : roles) {
|
||||||
if (checkType.hasRole(role)) {
|
if (checkType.hasRole(role)) {
|
||||||
principals.add(new RolePrincipal(role.getName()));
|
try {
|
||||||
|
principals.add(createGroupPrincipal(role.getName(), rolePrincipalClass));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
logger.info("Can't add role principal", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return principals;
|
return principals;
|
||||||
|
@ -160,4 +179,71 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRolePrincipalClass() {
|
||||||
|
return rolePrincipalClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRolePrincipalClass(String rolePrincipalClass) {
|
||||||
|
this.rolePrincipalClass = rolePrincipalClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object createGroupPrincipal(String name, String groupClass) throws Exception {
|
||||||
|
if (WILDCARD.equals(name)) {
|
||||||
|
// simple match all group principal - match any name and class
|
||||||
|
return new Principal() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return WILDCARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return WILDCARD.hashCode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Object[] param = new Object[]{name};
|
||||||
|
|
||||||
|
Class<?> cls = Class.forName(groupClass);
|
||||||
|
|
||||||
|
Constructor<?>[] constructors = cls.getConstructors();
|
||||||
|
int i;
|
||||||
|
Object instance;
|
||||||
|
for (i = 0; i < constructors.length; i++) {
|
||||||
|
Class<?>[] paramTypes = constructors[i].getParameterTypes();
|
||||||
|
if (paramTypes.length != 0 && paramTypes[0].equals(String.class)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < constructors.length) {
|
||||||
|
instance = constructors[i].newInstance(param);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instance = cls.newInstance();
|
||||||
|
Method[] methods = cls.getMethods();
|
||||||
|
i = 0;
|
||||||
|
for (i = 0; i < methods.length; i++) {
|
||||||
|
Class<?>[] paramTypes = methods[i].getParameterTypes();
|
||||||
|
if (paramTypes.length != 0 && methods[i].getName().equals("setName") && paramTypes[0].equals(String.class)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < methods.length) {
|
||||||
|
methods[i].invoke(instance, param);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new NoSuchMethodException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,11 @@ import org.osgi.framework.InvalidSyntaxException;
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.jms.Connection;
|
||||||
|
import javax.jms.Message;
|
||||||
|
import javax.jms.MessageConsumer;
|
||||||
|
import javax.jms.MessageProducer;
|
||||||
|
import javax.jms.Queue;
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -137,13 +142,17 @@ public class ArtemisFeatureTest extends Assert {
|
||||||
|
|
||||||
String amqpURI = "amqp://localhost:5672";
|
String amqpURI = "amqp://localhost:5672";
|
||||||
JmsConnectionFactory factory = new JmsConnectionFactory(amqpURI);
|
JmsConnectionFactory factory = new JmsConnectionFactory(amqpURI);
|
||||||
factory.setUsername(USER);
|
Connection connection = factory.createConnection(USER, PASSWORD);
|
||||||
factory.setPassword(PASSWORD);
|
connection.start();
|
||||||
|
|
||||||
//TODO fix security settings and test sending/receiving messages
|
javax.jms.Session sess = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
|
||||||
/*
|
Queue queue = sess.createQueue("jms.queue.exampleQueue");
|
||||||
Connection connection = factory.createConnection();
|
MessageProducer producer = sess.createProducer(queue);
|
||||||
connection.start();*/
|
producer.send(sess.createTextMessage("TEST"));
|
||||||
|
|
||||||
|
MessageConsumer consumer = sess.createConsumer(queue);
|
||||||
|
Message msg = consumer.receive(5000);
|
||||||
|
assertNotNull(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String executeCommand(final String command, final Long timeout, final Boolean silent) {
|
protected String executeCommand(final String command, final Long timeout, final Boolean silent) {
|
||||||
|
|
Loading…
Reference in New Issue