diff options
Diffstat (limited to 'java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java')
-rw-r--r-- | java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java | 101 |
1 files changed, 32 insertions, 69 deletions
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java index a2a0d2d093..8bc2afb176 100644 --- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java +++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java @@ -22,26 +22,22 @@ package org.apache.qpid.server.jmx; import org.apache.log4j.Logger; -import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.ManagementActor; -import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import javax.management.Attribute; import javax.management.JMException; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; -import javax.management.Notification; -import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.RuntimeErrorException; -import javax.management.remote.JMXConnectionNotification; -import javax.management.remote.JMXPrincipal; import javax.management.remote.MBeanServerForwarder; import javax.security.auth.Subject; import java.lang.reflect.InvocationHandler; @@ -51,27 +47,32 @@ import java.lang.reflect.Proxy; import java.security.AccessControlContext; import java.security.AccessController; import java.util.Arrays; -import java.util.Map; -import java.util.Set; /** * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates * JMX access decisions to the SecurityPlugin. */ -public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener +public class MBeanInvocationHandlerImpl implements InvocationHandler { private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class); - private final IApplicationRegistry _appRegistry = ApplicationRegistry.getInstance(); private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate"; private MBeanServer _mbs; - private final ManagementActor _logActor = new ManagementActor(_appRegistry.getRootMessageLogger()); - private final boolean _managementRightsInferAllAccess = - _appRegistry.getConfiguration().getManagementRightsInferAllAccess(); + private final ManagementActor _logActor; - public static MBeanServerForwarder newProxyInstance() + private final boolean _managementRightsInferAllAccess; + private final Broker _broker; + + MBeanInvocationHandlerImpl(Broker broker) + { + _managementRightsInferAllAccess = Boolean.valueOf(System.getProperty(BrokerProperties.PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS, "true")); + _broker = broker; + _logActor = new ManagementActor(broker.getRootMessageLogger()); + } + + public static MBeanServerForwarder newProxyInstance(Broker broker) { - final InvocationHandler handler = new MBeanInvocationHandlerImpl(); + final InvocationHandler handler = new MBeanInvocationHandlerImpl(broker); final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class }; Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler); @@ -101,7 +102,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati { ObjectName mbean = (ObjectName) args[0]; - if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain())) + if(!ManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain())) { return true; } @@ -151,11 +152,13 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati return method.invoke(_mbs, args); } - // Retrieve JMXPrincipal from Subject - Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class); - if (principals == null || principals.isEmpty()) + try + { + AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject); + } + catch(Exception e) { - throw new SecurityException("Access denied: no JMX principal"); + throw new SecurityException("Access denied: no authenticated principal", e); } // Save the subject @@ -211,11 +214,16 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati SecurityManager security; if (vhost == null) { - security = _appRegistry.getSecurityManager(); + security = _broker.getSecurityManager(); } else { - security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager(); + VirtualHost virtualHost = _broker.findVirtualHostByName(vhost); + if (virtualHost == null) + { + throw new IllegalArgumentException("Virtual host with name '" + vhost + "' is not found."); + } + security = virtualHost.getSecurityManager(); } methodName = getMethodName(method, args); @@ -360,50 +368,5 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati return (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("is")); } - /** - * Receives notifications from the MBeanServer. - */ - public void handleNotification(final Notification notification, final Object handback) - { - assert notification instanceof JMXConnectionNotification; - - final String connectionId = ((JMXConnectionNotification) notification).getConnectionId(); - final String type = notification.getType(); - - if (_logger.isDebugEnabled()) - { - _logger.debug("Notification connectionId : " + connectionId + " type : " + type - + " Notification handback : " + handback); - } - - // Normally JMXManagedObjectRegistry provides a Map as handback data containing a map - // between connection id and username. - String user = null; - if (handback instanceof Map) - { - final Map<String, String> connectionIdUsernameMap = (Map<String, String>) handback; - user = connectionIdUsernameMap.get(connectionId); - } - - // If user is still null, fallback to an unordered list of Principals from the connection id. - if (user == null) - { - final String[] splitConnectionId = connectionId.split(" "); - user = splitConnectionId[1]; - } - - // use a separate instance of actor as subject is not set on connect/disconnect - // we need to pass principal name explicitly into log actor - LogActor logActor = new ManagementActor(_appRegistry.getRootMessageLogger(), user); - if (JMXConnectionNotification.OPENED.equals(type)) - { - logActor.message(ManagementConsoleMessages.OPEN(user)); - } - else if (JMXConnectionNotification.CLOSED.equals(type) || - JMXConnectionNotification.FAILED.equals(type)) - { - logActor.message(ManagementConsoleMessages.CLOSE(user)); - } - } } |