Author: kwall Date: Mon Sep 10 15:37:45 2012 New Revision: 1382947 URL: http://svn.apache.org/viewvc?rev=1382947&view=rev Log: QPID-4292: add ACL rule to authorise access to the web management UI
* added object name MANAGEMENT to represent both JMX and Web Management layers * Change both JMX/Web entry points to permission access with an access management check * Updated examples and docbook * Made Principals serialised to avoid container warnings when Qpid principals are placed within a HttpSession. Work of Robbie Gemmell <rob...@apache.org> and myself. Modified: qpid/trunk/qpid/doc/book/src/java-broker/Configure-ACLs.xml qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java qpid/trunk/qpid/java/broker/etc/broker_example.acl qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java Modified: qpid/trunk/qpid/doc/book/src/java-broker/Configure-ACLs.xml URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/doc/book/src/java-broker/Configure-ACLs.xml?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/doc/book/src/java-broker/Configure-ACLs.xml (original) +++ qpid/trunk/qpid/doc/book/src/java-broker/Configure-ACLs.xml Mon Sep 10 15:37:45 2012 @@ -215,36 +215,40 @@ <tgroup cols="2"> <tbody> <row> - <entry> <command>QUEUE</command> </entry> - <entry> <para> A queue </para> </entry> + <entry> <command>VIRTUALHOST</command> </entry> + <entry> <para>A virtualhost (Java Broker only)</para> </entry> </row> <row> - <entry> <command>EXCHANGE</command> </entry> - <entry> <para> An exchange </para> </entry> + <entry> <command>MANAGEMENT </command> </entry> + <entry> <para>Management - for web and JMX (Java Broker only)</para> </entry> </row> <row> - <entry> <command>VIRTUALHOST</command> </entry> - <entry> <para> A virtualhost (Java Broker only)</para> </entry> + <entry> <command>QUEUE</command> </entry> + <entry> <para>A queue </para> </entry> + </row> + <row> + <entry> <command>EXCHANGE</command> </entry> + <entry> <para>An exchange </para> </entry> </row> <row> <entry> <command>USER</command> </entry> - <entry> <para> A user (Java Broker only)</para> </entry> + <entry> <para>A user (Java Broker only)</para> </entry> </row> <row> <entry> <command>GROUP</command> </entry> - <entry> <para> A group (Java Broker only)</para> </entry> + <entry> <para>A group (Java Broker only)</para> </entry> </row> <row> <entry> <command>METHOD</command> </entry> - <entry> <para> Management or agent or broker method (Java Broker only)</para> </entry> + <entry> <para>Management or agent or broker method (Java Broker only)</para> </entry> </row> <row> - <entry> <command>BROKER</command> </entry> - <entry> <para> The broker (not currently used in Java Broker)</para> </entry> + <entry> <command>LINK</command> </entry> + <entry> <para>A federation or inter-broker link (not currently used in Java Broker)</para> </entry> </row> <row> - <entry> <command>LINK</command> </entry> - <entry> <para> A federation or inter-broker link (not currently used in Java Broker)</para> </entry> + <entry> <command>BROKER</command> </entry> + <entry> <para>The broker (not currently used in Java Broker)</para> </entry> </row> </tbody> </tgroup> @@ -387,8 +391,9 @@ is allowed to perform user maintainence This example illustrates the permissioning of an individual component. </para> <programlisting> - # Give usermaint permission to execute all JMX Methods on the + # Give usermaint access to management and permission to execute all JMX Methods on the # UserManagement MBean and perform all actions for USER objects + ACL ALLOW usermaint ACCESS MANAGEMENT ACL ALLOW usermaint ALL METHOD component="UserManagement" ACL ALLOW usermaint ALL USER ACL DENY ALL ALL METHOD component="UserManagement" Modified: qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java (original) +++ qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java Mon Sep 10 15:37:45 2012 @@ -438,6 +438,15 @@ public class PlainConfigurationTest exte } } + public void testManagementRuleParsing() throws Exception + { + validateRule(writeACLConfig("ACL ALLOW user1 ALL MANAGEMENT"), + "user1", Operation.ALL, ObjectType.MANAGEMENT, ObjectProperties.EMPTY); + + validateRule(writeACLConfig("ACL ALLOW user1 ACCESS MANAGEMENT"), + "user1", Operation.ACCESS, ObjectType.MANAGEMENT, ObjectProperties.EMPTY); + } + private void validateRule(final PlainConfiguration config, String username, Operation operation, ObjectType objectType, ObjectProperties objectProperties) { final RuleSet rs = config.getConfiguration(); Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java (original) +++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java Mon Sep 10 15:37:45 2012 @@ -43,6 +43,7 @@ import org.apache.qpid.server.logging.ac import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; @@ -50,11 +51,10 @@ import org.apache.qpid.server.security.a public abstract class AbstractServlet extends HttpServlet { - private static final String ATTR_LOGIN_LOGOUT_REPORTER = "attrLoginLogoutReporter"; - private static final Logger LOGGER = Logger.getLogger(AbstractServlet.class); - protected static final String ATTR_SUBJECT = "subject"; + private static final String ATTR_LOGIN_LOGOUT_REPORTER = "AbstractServlet.loginLogoutReporter"; + private static final String ATTR_SUBJECT = "AbstractServlet.subject"; private static final String ATTR_LOG_ACTOR = "AbstractServlet.logActor"; private final Broker _broker; @@ -193,9 +193,18 @@ public abstract class AbstractServlet ex final HttpServletRequest request, final HttpServletResponse resp) { - Subject subject = getAndCacheAuthorizedSubject(request); - org.apache.qpid.server.security.SecurityManager.setThreadSubject(subject); + Subject subject; + try + { + subject = getAndCacheAuthorizedSubject(request); + } + catch (AccessControlException e) + { + sendError(resp, HttpServletResponse.SC_FORBIDDEN); + return; + } + SecurityManager.setThreadSubject(subject); try { HttpManagementActor logActor = getLogActorAndCacheInSession(request); @@ -223,7 +232,7 @@ public abstract class AbstractServlet ex { try { - org.apache.qpid.server.security.SecurityManager.setThreadSubject(null); + SecurityManager.setThreadSubject(null); } finally { @@ -247,7 +256,7 @@ public abstract class AbstractServlet ex private Subject getAndCacheAuthorizedSubject(HttpServletRequest request) { HttpSession session = request.getSession(); - Subject subject = getSubjectFromSession(session); + Subject subject = getAuthorisedSubjectFromSession(session); if(subject != null) { @@ -255,6 +264,65 @@ public abstract class AbstractServlet ex } SubjectCreator subjectCreator = ApplicationRegistry.getInstance().getSubjectCreator(getSocketAddress(request)); + subject = authenticate(request, subjectCreator); + if (subject != null) + { + authoriseManagement(request, subject); + setAuthorisedSubjectInSession(subject, request, session); + } + else + { + subject = subjectCreator.createSubjectWithGroups(AnonymousAuthenticationManager.ANONYMOUS_USERNAME); + } + + return subject; + } + + protected void authoriseManagement(HttpServletRequest request, Subject subject) + { + // TODO: We should eliminate SecurityManager.setThreadSubject in favour of Subject.doAs + SecurityManager.setThreadSubject(subject); // Required for accessManagement check + LogActor actor = createHttpManagementActor(request); + CurrentActor.set(actor); + try + { + try + { + Subject.doAs(subject, new PrivilegedExceptionAction<Void>() // Required for proper logging of Subject + { + @Override + public Void run() throws Exception + { + boolean allowed = ApplicationRegistry.getInstance().getSecurityManager().accessManagement(); + if (!allowed) + { + throw new AccessControlException("User is not authorised for management"); + } + return null; + } + }); + } + catch (PrivilegedActionException e) + { + throw new RuntimeException("Unable to perform access check", e); + } + } + finally + { + try + { + CurrentActor.remove(); + } + finally + { + SecurityManager.setThreadSubject(null); + } + } + } + + private Subject authenticate(HttpServletRequest request, SubjectCreator subjectCreator) + { + Subject subject = null; String remoteUser = request.getRemoteUser(); if(remoteUser != null) @@ -268,8 +336,7 @@ public abstract class AbstractServlet ex if (header != null) { String[] tokens = header.split("\\s"); - if(tokens.length >= 2 - && "BASIC".equalsIgnoreCase(tokens[0])) + if(tokens.length >= 2 && "BASIC".equalsIgnoreCase(tokens[0])) { if(!isBasicAuthSupported(request)) { @@ -277,30 +344,27 @@ public abstract class AbstractServlet ex throw new IllegalArgumentException("BASIC Authorization is not enabled."); } - String[] credentials = (new String(Base64.decodeBase64(tokens[1].getBytes()))).split(":",2); - if(credentials.length == 2) - { - subject = authenticateUserAndGetSubject(subjectCreator, credentials[0], credentials[1]); - } - else - { - //TODO: write a return response indicating failure? - throw new AccessControlException("Invalid number of credentials supplied: " - + credentials.length); - } + subject = performBasicAuth(subject, subjectCreator, tokens[1]); } } } - if (subject != null) + return subject; + } + + private Subject performBasicAuth(Subject subject,SubjectCreator subjectCreator, String base64UsernameAndPassword) + { + String[] credentials = (new String(Base64.decodeBase64(base64UsernameAndPassword.getBytes()))).split(":",2); + if(credentials.length == 2) { - setSubjectInSession(subject, request, session); + subject = authenticateUserAndGetSubject(subjectCreator, credentials[0], credentials[1]); } else { - subject = subjectCreator.createSubjectWithGroups(AnonymousAuthenticationManager.ANONYMOUS_USERNAME); + //TODO: write a return response indicating failure? + throw new AccessControlException("Invalid number of credentials supplied: " + + credentials.length); } - return subject; } @@ -336,12 +400,12 @@ public abstract class AbstractServlet ex return actor; } - protected Subject getSubjectFromSession(HttpSession session) + protected Subject getAuthorisedSubjectFromSession(HttpSession session) { return (Subject)session.getAttribute(ATTR_SUBJECT); } - protected void setSubjectInSession(Subject subject, HttpServletRequest request, final HttpSession session) + protected void setAuthorisedSubjectInSession(Subject subject, HttpServletRequest request, final HttpSession session) { session.setAttribute(ATTR_SUBJECT, subject); @@ -360,9 +424,22 @@ public abstract class AbstractServlet ex return InetSocketAddress.createUnresolved(request.getServerName(), request.getServerPort()); } + protected void sendError(final HttpServletResponse resp, int errorCode) + { + try + { + resp.sendError(errorCode); + } + catch (IOException e) + { + throw new RuntimeException("Failed to send error response code " + errorCode, e); + } + } + private HttpManagementActor createHttpManagementActor(HttpServletRequest request) { return new HttpManagementActor(_rootLogger, request.getRemoteAddr(), request.getRemotePort()); } + } Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java (original) +++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java Mon Sep 10 15:37:45 2012 @@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletRes import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; +import java.security.AccessControlException; import java.security.Principal; import java.security.SecureRandom; import java.util.LinkedHashMap; @@ -85,7 +86,7 @@ public class SaslServlet extends Abstrac String[] mechanisms = subjectCreator.getMechanisms().split(" "); Map<String, Object> outputObject = new LinkedHashMap<String, Object>(); - final Subject subject = getSubjectFromSession(session); + final Subject subject = getAuthorisedSubjectFromSession(session); if(subject != null) { Principal principal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject); @@ -236,8 +237,17 @@ public class SaslServlet extends Abstrac { Subject subject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID()); - setSubjectInSession(subject, request, session); + try + { + authoriseManagement(request, subject); + } + catch (AccessControlException ace) + { + sendError(response, HttpServletResponse.SC_FORBIDDEN); + return; + } + setAuthorisedSubjectInSession(subject, request, session); session.removeAttribute(ATTR_ID); session.removeAttribute(ATTR_SASL_SERVER); session.removeAttribute(ATTR_EXPIRY); Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java (original) +++ qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java Mon Sep 10 15:37:45 2012 @@ -89,6 +89,7 @@ public class GroupRestACLTest extends Qp public void testCreateGroup() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE GROUP", "ACL DENY-LOG " + DENIED_GROUP + " CREATE GROUP"); @@ -116,6 +117,7 @@ public class GroupRestACLTest extends Qp public void testDeleteGroup() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE GROUP", "ACL DENY-LOG " + DENIED_GROUP + " DELETE GROUP"); @@ -143,6 +145,7 @@ public class GroupRestACLTest extends Qp public void testUpdateGroupAddMember() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP", "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP"); @@ -163,6 +166,7 @@ public class GroupRestACLTest extends Qp public void testUpdateGroupDeleteMember() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP", "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP"); Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java (original) +++ qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java Mon Sep 10 15:37:45 2012 @@ -91,6 +91,7 @@ public class UserRestACLTest extends Qpi public void testAddUser() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE USER", "ACL DENY-LOG " + DENIED_GROUP + " CREATE USER"); @@ -115,6 +116,7 @@ public class UserRestACLTest extends Qpi public void testDeleteUser() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE USER", "ACL DENY-LOG " + DENIED_GROUP + " DELETE USER"); @@ -135,6 +137,7 @@ public class UserRestACLTest extends Qpi public void testUpdateUser() throws Exception { AbstractACLTestCase.writeACLFileUtil(this, null, + "ACL ALLOW-LOG ALL ACCESS MANAGEMENT", "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE USER", "ACL DENY-LOG " + DENIED_GROUP + " UPDATE USER"); Modified: qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java (original) +++ qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java Mon Sep 10 15:37:45 2012 @@ -199,7 +199,7 @@ public class JMXManagedObjectRegistry im } //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server - RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(_jmxPortRegistryServer)); + RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(ApplicationRegistry.getInstance(), new InetSocketAddress(_jmxPortRegistryServer)); HashMap<String,Object> env = new HashMap<String,Object>(); env.put(JMXConnectorServer.AUTHENTICATOR, rmipa); Modified: qpid/trunk/qpid/java/broker/etc/broker_example.acl URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/etc/broker_example.acl?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/etc/broker_example.acl (original) +++ qpid/trunk/qpid/java/broker/etc/broker_example.acl Mon Sep 10 15:37:45 2012 @@ -23,9 +23,12 @@ ### JMX MANAGEMENT #### -# Allow everyone to perform read operations on the ServerInformation mbean -# This is used for items such as querying the management API and broker release versions. -ACL ALLOW ALL ACCESS METHOD component="ServerInformation" +# To use JMX management, first give the user/group ACCESS MANAGEMENT permission +ACL ALLOW administrators ACCESS MANAGEMENT +ACL ALLOW guest ACCESS MANAGEMENT + +# Allow guest to perform read operations on the ServerInformation mbean +ACL ALLOW guest ACCESS METHOD component="ServerInformation" # Allow 'administrators' all management operations. To reduce log file noise, only non-read-only operations are logged. ACL ALLOW administrators ACCESS METHOD @@ -42,33 +45,13 @@ ACL DENY-LOG ALL ACCESS METHOD component ACL DENY-LOG ALL ACCESS METHOD component="ConfigurationManagement" ACL DENY-LOG ALL ACCESS METHOD component="LoggingManagement" -# Allow everyone to perform all read operations (using ALLOW rather than ALLOW-LOG to reduce log file noise) -# on the mbeans not listed in the DENY rules above +# Allow everyone to perform all read operations on the mbeans not listed in the DENY rules above ACL ALLOW ALL ACCESS METHOD -### MESSAGING ### - -#Example permissions for request-response based messaging. - -#Allow 'messaging-users' group to connect to the virtualhost -ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST - -# Client side -# Allow the 'client' user to publish requests to the request queue and create, consume from, and delete temporary reply queues. -ACL ALLOW-LOG client CREATE QUEUE temporary="true" -ACL ALLOW-LOG client CONSUME QUEUE temporary="true" -ACL ALLOW-LOG client DELETE QUEUE temporary="true" -ACL ALLOW-LOG client BIND EXCHANGE name="amq.direct" temporary="true" -ACL ALLOW-LOG client UNBIND EXCHANGE name="amq.direct" temporary="true" -ACL ALLOW-LOG client PUBLISH EXCHANGE name="amq.direct" routingKey="example.RequestQueue" +### WEB MANAGEMENT #### -# Server side -# Allow the 'server' user to create and consume from the request queue and publish a response to the temporary response queue created by -# client. -ACL ALLOW-LOG server CREATE QUEUE name="example.RequestQueue" -ACL ALLOW-LOG server CONSUME QUEUE name="example.RequestQueue" -ACL ALLOW-LOG server BIND EXCHANGE -ACL ALLOW-LOG server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*" +# To use web management, first give the user/group ACCESS MANAGEMENT permission +ACL ALLOW webadmins ACCESS MANAGEMENT # ACL for web management console admins # All rules below are required for console admin users @@ -94,6 +77,34 @@ ACL ALLOW-LOG webadmins UPDATE METHOD #ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="copyMessages" #ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="deleteMessages" +### MESSAGING ### + +#Example permissions for request-response based messaging. + +#Allow 'messaging-users' group to connect to all virtualhosts +ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST +# Deny messaging-users management +ACL DENY-LOG messaging-users ACCESS MANAGEMENT + + +# Client side +# Allow the 'client' user to publish requests to the request queue and create, consume from, and delete temporary reply queues. +ACL ALLOW-LOG client CREATE QUEUE temporary="true" +ACL ALLOW-LOG client CONSUME QUEUE temporary="true" +ACL ALLOW-LOG client DELETE QUEUE temporary="true" +ACL ALLOW-LOG client BIND EXCHANGE name="amq.direct" temporary="true" +ACL ALLOW-LOG client UNBIND EXCHANGE name="amq.direct" temporary="true" +ACL ALLOW-LOG client PUBLISH EXCHANGE name="amq.direct" routingKey="example.RequestQueue" + +# Server side +# Allow the 'server' user to create and consume from the request queue and publish a response to the temporary response queue created by +# client. +ACL ALLOW-LOG server CREATE QUEUE name="example.RequestQueue" +ACL ALLOW-LOG server CONSUME QUEUE name="example.RequestQueue" +ACL ALLOW-LOG server BIND EXCHANGE +ACL ALLOW-LOG server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*" + + ### DEFAULT ### # Deny all users from performing all operations Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java Mon Sep 10 15:37:45 2012 @@ -29,6 +29,7 @@ import org.apache.qpid.server.exchange.E import org.apache.qpid.server.plugins.PluginManager; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.security.access.ObjectProperties; +import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE; @@ -359,6 +360,17 @@ public class SecurityManager }); } + public boolean accessManagement() + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(SecurityPlugin plugin) + { + return plugin.access(ObjectType.MANAGEMENT, null); + } + }); + } + public boolean accessVirtualhost(final String vhostname, final SocketAddress remoteAddress) { return checkAllPlugins(new AccessCheck() Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java Mon Sep 10 15:37:45 2012 @@ -41,6 +41,7 @@ public enum ObjectType { ALL(Operation.ALL), VIRTUALHOST(Operation.ALL, ACCESS), + MANAGEMENT(Operation.ALL, ACCESS), QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME), EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH), LINK, // Not allowed in the Java broker Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java Mon Sep 10 15:37:45 2012 @@ -18,6 +18,7 @@ */ package org.apache.qpid.server.security.auth; +import java.io.Serializable; import java.security.Principal; import java.util.Set; @@ -30,7 +31,7 @@ import org.apache.qpid.server.security.a * by calling {@link Subject#getPrincipals(Class)}, passing in {@link AuthenticatedPrincipal}.class, * e.g. when logging. */ -public final class AuthenticatedPrincipal implements Principal +public final class AuthenticatedPrincipal implements Principal, Serializable { private final Principal _wrappedPrincipal; Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java Mon Sep 10 15:37:45 2012 @@ -20,10 +20,11 @@ */ package org.apache.qpid.server.security.auth; +import java.io.Serializable; import java.security.Principal; /** A principal that is just a wrapper for a simple username. */ -public class UsernamePrincipal implements Principal +public class UsernamePrincipal implements Principal, Serializable { private final String _name; Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java Mon Sep 10 15:37:45 2012 @@ -22,7 +22,8 @@ package org.apache.qpid.server.security. import java.net.SocketAddress; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; @@ -37,23 +38,33 @@ public class RMIPasswordAuthenticator im static final String SHOULD_HAVE_2_ELEMENTS = "User details should have 2 elements, username, password"; static final String SHOULD_BE_NON_NULL = "Supplied username and password should be non-null"; static final String INVALID_CREDENTIALS = "Invalid user details supplied"; + static final String USER_NOT_AUTHORISED_FOR_MANAGEMENT = "User not authorised for management"; static final String CREDENTIALS_REQUIRED = "User details are required. " + - "Please ensure you are using an up to date management console to connect."; + "Please ensure you are using an up to date management console to connect."; - private SubjectCreator _subjectCreator = null; - private SocketAddress _socketAddress; + private final IApplicationRegistry _appRegistry; + private final SocketAddress _socketAddress; - public RMIPasswordAuthenticator(SocketAddress socketAddress) + public RMIPasswordAuthenticator(IApplicationRegistry appRegistry, SocketAddress socketAddress) { + _appRegistry = appRegistry; _socketAddress = socketAddress; } - public void setSubjectCreator(final SubjectCreator subjectCreator) + public Subject authenticate(Object credentials) throws SecurityException { - _subjectCreator = subjectCreator; + validateCredentials(credentials); + + final String[] userCredentials = (String[]) credentials; + final String username = (String) userCredentials[0]; + final String password = (String) userCredentials[1]; + + final Subject authenticatedSubject = doAuthentication(username, password); + doManagementAuthorisation(authenticatedSubject); + return authenticatedSubject; } - public Subject authenticate(Object credentials) throws SecurityException + private void validateCredentials(Object credentials) { // Verify that credential's are of type String[]. if (!(credentials instanceof String[])) @@ -69,41 +80,27 @@ public class RMIPasswordAuthenticator im } // Verify that required number of credentials. - final String[] userCredentials = (String[]) credentials; - if (userCredentials.length != 2) + if (((String[])credentials).length != 2) { throw new SecurityException(SHOULD_HAVE_2_ELEMENTS); } + } - final String username = (String) userCredentials[0]; - final String password = (String) userCredentials[1]; - + private Subject doAuthentication(final String username, final String password) + { // Verify that all required credentials are actually present. if (username == null || password == null) { throw new SecurityException(SHOULD_BE_NON_NULL); } - // Verify that an SubjectCreator has been set. - if (_subjectCreator == null) + SubjectCreator subjectCreator = _appRegistry.getSubjectCreator(_socketAddress); + if (subjectCreator == null) { - try - { - if(ApplicationRegistry.getInstance().getSubjectCreator(_socketAddress) != null) - { - _subjectCreator = ApplicationRegistry.getInstance().getSubjectCreator(_socketAddress); - } - else - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } - } - catch(IllegalStateException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } + throw new SecurityException("Can't get subject creator for " + _socketAddress); } - final SubjectAuthenticationResult result = _subjectCreator.authenticate(username, password); + + final SubjectAuthenticationResult result = subjectCreator.authenticate(username, password); if (AuthenticationStatus.ERROR.equals(result.getStatus())) { @@ -119,4 +116,21 @@ public class RMIPasswordAuthenticator im } } + private void doManagementAuthorisation(Subject authenticatedSubject) + { + SecurityManager.setThreadSubject(authenticatedSubject); + try + { + if (!_appRegistry.getSecurityManager().accessManagement()) + { + throw new SecurityException(USER_NOT_AUTHORISED_FOR_MANAGEMENT); + } + } + finally + { + SecurityManager.setThreadSubject(null); + } + } + + } \ No newline at end of file Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java Mon Sep 10 15:37:45 2012 @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.security.group; +import java.io.Serializable; import java.security.Principal; import java.security.acl.Group; import java.util.Enumeration; @@ -30,7 +31,7 @@ import java.util.Enumeration; * methods etc throw {@link UnsupportedOperationException}. * */ -public class GroupPrincipal implements Group +public class GroupPrincipal implements Group, Serializable { /** Name of the group */ private final String _groupName; Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java (original) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java Mon Sep 10 15:37:45 2012 @@ -31,10 +31,12 @@ import javax.security.auth.Subject; import junit.framework.TestCase; +import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.SecurityManager; /** * Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager. @@ -42,17 +44,25 @@ import org.apache.qpid.server.security.a */ public class RMIPasswordAuthenticatorTest extends TestCase { - private static final Subject SUBJECT = new Subject(); - private final String USERNAME = "guest"; - private final String PASSWORD = "guest"; + private static final String USERNAME = "guest"; + private static final String PASSWORD = "password"; + + private final ApplicationRegistry _applicationRegistry = mock(ApplicationRegistry.class); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final InetSocketAddress _jmxSocketAddress = new InetSocketAddress(8999); + private final Subject _loginSubject = new Subject(); + private final String[] _credentials = new String[] {USERNAME, PASSWORD}; + private RMIPasswordAuthenticator _rmipa; - private String[] _credentials; + + private SubjectCreator _usernamePasswordOkaySuvjectCreator = createMockSubjectCreator(true, null); + private SubjectCreator _badPasswordSubjectCreator = createMockSubjectCreator(false, null); protected void setUp() throws Exception { - _rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(5672)); + _rmipa = new RMIPasswordAuthenticator(_applicationRegistry, _jmxSocketAddress); - _credentials = new String[] {USERNAME, PASSWORD}; + when(_applicationRegistry.getSecurityManager()).thenReturn(_securityManager); } /** @@ -60,10 +70,11 @@ public class RMIPasswordAuthenticatorTes */ public void testAuthenticationSuccess() { - _rmipa.setSubjectCreator(createMockSubjectCreator(true, null)); + when(_applicationRegistry.getSubjectCreator(_jmxSocketAddress)).thenReturn(_usernamePasswordOkaySuvjectCreator); + when(_securityManager.accessManagement()).thenReturn(true); Subject newSubject = _rmipa.authenticate(_credentials); - assertSame("Subject must be unchanged", SUBJECT, newSubject); + assertSame("Subject must be unchanged", _loginSubject, newSubject); } /** @@ -71,7 +82,7 @@ public class RMIPasswordAuthenticatorTes */ public void testUsernameOrPasswordInvalid() { - _rmipa.setSubjectCreator(createMockSubjectCreator(false, null)); + when(_applicationRegistry.getSubjectCreator(_jmxSocketAddress)).thenReturn(_badPasswordSubjectCreator); try { @@ -82,17 +93,31 @@ public class RMIPasswordAuthenticatorTes { assertEquals("Unexpected exception message", RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage()); + } + } + + public void testAuthorisationFailure() + { + when(_applicationRegistry.getSubjectCreator(_jmxSocketAddress)).thenReturn(_usernamePasswordOkaySuvjectCreator); + when(_securityManager.accessManagement()).thenReturn(false); + try + { + _rmipa.authenticate(_credentials); + fail("Exception not thrown"); + } + catch (SecurityException se) + { + assertEquals("Unexpected exception message", + RMIPasswordAuthenticator.USER_NOT_AUTHORISED_FOR_MANAGEMENT, se.getMessage()); } } - /** - * Tests case where authentication system itself fails. - */ - public void testAuthenticationFailure() + public void testSubjectCreatorInternalFailure() { final Exception mockAuthException = new Exception("Mock Auth system failure"); - _rmipa.setSubjectCreator(createMockSubjectCreator(false, mockAuthException)); + SubjectCreator subjectCreator = createMockSubjectCreator(false, mockAuthException); + when(_applicationRegistry.getSubjectCreator(_jmxSocketAddress)).thenReturn(subjectCreator); try { @@ -105,13 +130,13 @@ public class RMIPasswordAuthenticatorTes } } - /** * Tests case where authentication manager is not set. */ - public void testNullAuthenticationManager() throws Exception + public void testNullSubjectCreator() throws Exception { - _rmipa.setSubjectCreator(null); + when(_applicationRegistry.getSubjectCreator(_jmxSocketAddress)).thenReturn(null); + try { _rmipa.authenticate(_credentials); @@ -120,7 +145,7 @@ public class RMIPasswordAuthenticatorTes catch (SecurityException se) { assertEquals("Unexpected exception message", - RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage()); + "Can't get subject creator for 0.0.0.0/0.0.0.0:8999", se.getMessage()); } } @@ -148,11 +173,13 @@ public class RMIPasswordAuthenticatorTes */ public void testWithIllegalNumberOfArguments() { + String[] credentials; + // Test handling of incorrect number of credentials try { - _credentials = new String[]{USERNAME, PASSWORD, PASSWORD}; - _rmipa.authenticate(_credentials); + credentials = new String[]{USERNAME, PASSWORD, PASSWORD}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to supplying wrong number of credentials"); } catch (SecurityException se) @@ -165,8 +192,8 @@ public class RMIPasswordAuthenticatorTes try { //send a null array - _credentials = null; - _rmipa.authenticate(_credentials); + credentials = null; + _rmipa.authenticate(credentials); fail("SecurityException expected due to not supplying an array of credentials"); } catch (SecurityException se) @@ -178,8 +205,8 @@ public class RMIPasswordAuthenticatorTes try { //send a null password - _credentials = new String[]{USERNAME, null}; - _rmipa.authenticate(_credentials); + credentials = new String[]{USERNAME, null}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to sending a null password"); } catch (SecurityException se) @@ -191,8 +218,8 @@ public class RMIPasswordAuthenticatorTes try { //send a null username - _credentials = new String[]{null, PASSWORD}; - _rmipa.authenticate(_credentials); + credentials = new String[]{null, PASSWORD}; + _rmipa.authenticate(credentials); fail("SecurityException expected due to sending a null username"); } catch (SecurityException se) @@ -217,7 +244,7 @@ public class RMIPasswordAuthenticatorTes { subjectAuthenticationResult = new SubjectAuthenticationResult( - new AuthenticationResult(mock(Principal.class)), SUBJECT); + new AuthenticationResult(mock(Principal.class)), _loginSubject); } else { Modified: qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java?rev=1382947&r1=1382946&r2=1382947&view=diff ============================================================================== --- qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java (original) +++ qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java Mon Sep 10 15:37:45 2012 @@ -54,15 +54,14 @@ public class ExternalACLJMXTest extends super.tearDown(); } - /** - * Ensure an empty ACL defaults to DENY ALL. - */ - public void setUpDenyAllIsDefault() throws Exception + public void setUpDenyAllIsCatchAllRule() throws Exception { - writeACLFile(null, "#Empty ACL file"); + writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", + "#No more rules, default catch all (deny all) should apply"); } - public void testDenyAllIsDefault() throws Exception + public void testDenyAllIsCatchAllRule() throws Exception { //try a broker-level method ServerInformation info = _jmx.getServerInformation(); @@ -115,6 +114,7 @@ public class ExternalACLJMXTest extends public void setUpVhostAllowOverridesGlobalDeny() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); writeACLFile(TEST_VHOST, "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); @@ -144,6 +144,7 @@ public class ExternalACLJMXTest extends public void setUpUpdateComponentOnlyAllow() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager'"); } @@ -162,6 +163,7 @@ public class ExternalACLJMXTest extends public void setUpUpdateMethodOnlyAllow() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL ALLOW admin UPDATE METHOD"); } @@ -179,8 +181,8 @@ public class ExternalACLJMXTest extends */ public void setUpCreateQueueSuccess() throws Exception { - writeACLFile(TEST_VHOST, - "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); + writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT"); + writeACLFile(TEST_VHOST, "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); } public void testCreateQueueSuccess() throws Exception @@ -194,6 +196,7 @@ public class ExternalACLJMXTest extends */ public void setUpCreateQueueSuccessNoAMQPRights() throws Exception { + writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT"); writeACLFile(TEST_VHOST, "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'", "ACL DENY admin CREATE QUEUE"); @@ -210,6 +213,7 @@ public class ExternalACLJMXTest extends */ public void setUpCreateQueueDenied() throws Exception { + writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT"); writeACLFile(TEST_VHOST, "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); } @@ -234,6 +238,7 @@ public class ExternalACLJMXTest extends public void setUpServerInformationUpdateDenied() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL DENY admin UPDATE METHOD component='ServerInformation' name='resetStatistics'"); } @@ -258,6 +263,7 @@ public class ExternalACLJMXTest extends public void setUpServerInformationAccessGranted() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL ALLOW-LOG admin ACCESS METHOD component='ServerInformation' name='getManagementApiMajorVersion'"); } @@ -284,6 +290,7 @@ public class ExternalACLJMXTest extends public void setUpServerInformationUpdateMethodPermission() throws Exception { writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", "ACL ALLOW admin UPDATE METHOD component='ServerInformation' name='resetStatistics'"); } @@ -300,7 +307,9 @@ public class ExternalACLJMXTest extends */ public void setUpServerInformationAllMethodPermissions() throws Exception { - writeACLFile(null, "ACL ALLOW admin ALL METHOD component='ServerInformation'"); + writeACLFile(null, + "ACL ALLOW admin ACCESS MANAGEMENT", + "ACL ALLOW admin ALL METHOD component='ServerInformation'"); } public void testServerInformationAllMethodPermissions() throws Exception --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org