diff options
| author | Keith Wall <kwall@apache.org> | 2012-09-10 15:37:45 +0000 |
|---|---|---|
| committer | Keith Wall <kwall@apache.org> | 2012-09-10 15:37:45 +0000 |
| commit | b0a4911fa51737570a1e9767f7fd37f50f06b3bd (patch) | |
| tree | d3183ccd29662cd13926e529aa3f3d0f6db24ef3 /qpid/java/broker/src/main | |
| parent | 3957c7f5aab759d2a9b2f10b38c116f0472b32fa (diff) | |
| download | qpid-python-b0a4911fa51737570a1e9767f7fd37f50f06b3bd.tar.gz | |
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 <robbie@apache.org> and myself.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1382947 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src/main')
6 files changed, 64 insertions, 34 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java index ce0ea2faea..1e377be1d2 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java @@ -29,6 +29,7 @@ import org.apache.qpid.server.exchange.Exchange; 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() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java index 043d4909d5..8bc4b9d278 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java @@ -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 diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java index 96360e83e4..fb31132514 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java @@ -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.auth.UsernamePrincipal; * 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; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java index cc414f801a..5b3c1d59cf 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java @@ -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; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java index 808447b7ff..9f5d87bf62 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java @@ -22,7 +22,8 @@ package org.apache.qpid.server.security.auth.rmi; 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 implements JMXAuthenticator 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 implements JMXAuthenticator } // 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 implements JMXAuthenticator } } + 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 diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java index ccb446b719..a9590bb964 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java @@ -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; |
