Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java Wed Jul 13 14:53:08 2011 @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.protocol; +import javax.security.auth.Subject; import javax.security.sasl.SaslServer; import org.apache.qpid.AMQException; @@ -28,16 +29,15 @@ import org.apache.qpid.framing.*; import org.apache.qpid.AMQConnectionException; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.security.PrincipalHolder; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.virtualhost.VirtualHost; -import java.security.Principal; import java.util.List; -public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, PrincipalHolder, AMQConnectionModel +public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, AuthorizationHolder, AMQConnectionModel { long getSessionID(); @@ -205,7 +205,7 @@ public interface AMQProtocolSession exte public ProtocolOutputConverter getProtocolOutputConverter(); - void setAuthorizedID(Principal authorizedID); + void setAuthorizedSubject(Subject authorizedSubject); public java.net.SocketAddress getRemoteAddress();
Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java Wed Jul 13 14:53:08 2011 @@ -131,7 +131,7 @@ public class AMQProtocolSessionMBean ext public String getAuthorizedId() { - return (_protocolSession.getPrincipal() != null ) ? _protocolSession.getPrincipal().getName() : null; + return (_protocolSession.getAuthorizedPrincipal() != null ) ? _protocolSession.getAuthorizedPrincipal().getName() : null; } public String getVersion() Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java Wed Jul 13 14:53:08 2011 @@ -127,7 +127,7 @@ public class ProtocolEngine_0_10 extend public String getAuthId() { - return _connection.getAuthorizationID(); + return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName(); } public String getRemoteProcessName() Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java Wed Jul 13 14:53:08 2011 @@ -32,7 +32,7 @@ import org.apache.qpid.server.exchange.E import org.apache.qpid.server.exchange.ExchangeReferrer; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.security.PrincipalHolder; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.store.TransactionLogResource; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.txn.ServerTransaction; @@ -69,8 +69,8 @@ public interface AMQQueue extends Managa boolean isAutoDelete(); AMQShortString getOwner(); - PrincipalHolder getPrincipalHolder(); - void setPrincipalHolder(PrincipalHolder principalHolder); + AuthorizationHolder getAuthorizationHolder(); + void setAuthorizationHolder(AuthorizationHolder principalHolder); void setExclusiveOwningSession(AMQSessionModel owner); AMQSessionModel getExclusiveOwningSession(); Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java Wed Jul 13 14:53:08 2011 @@ -44,7 +44,7 @@ import org.apache.qpid.server.logging.su import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.PrincipalHolder; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionList; import org.apache.qpid.server.txn.AutoCommitTransaction; @@ -83,7 +83,7 @@ public class SimpleAMQQueue implements A /** null means shared */ private final AMQShortString _owner; - private PrincipalHolder _prinicpalHolder; + private AuthorizationHolder _authorizationHolder; private boolean _exclusive = false; private AMQSessionModel _exclusiveOwner; @@ -373,14 +373,14 @@ public class SimpleAMQQueue implements A return _owner; } - public PrincipalHolder getPrincipalHolder() + public AuthorizationHolder getAuthorizationHolder() { - return _prinicpalHolder; + return _authorizationHolder; } - public void setPrincipalHolder(PrincipalHolder prinicpalHolder) + public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder) { - _prinicpalHolder = prinicpalHolder; + _authorizationHolder = authorizationHolder; } Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java?rev=1146079&view=auto ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java (added) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java Wed Jul 13 14:53:08 2011 @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security; + +import java.security.Principal; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.sasl.GroupPrincipal; +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; + +/** + * Represents the authorization of the logged on user. + * + */ +public interface AuthorizationHolder +{ + /** + * Returns the {@link Subject} of the authorized user. This is guaranteed to + * contain at least one {@link UsernamePrincipal}, representing the the identity + * used when the user logged on to the application, and zero or more {@link GroupPrincipal} + * representing the group(s) to which the user belongs. + * + * @return the Subject + */ + Subject getAuthorizedSubject(); + + /** + * Returns the {@link Principal} representing the the identity + * used when the user logged on to the application. + * + * @return a Principal + */ + Principal getAuthorizedPrincipal(); +} Propchange: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java ------------------------------------------------------------------------------ svn:executable = * 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=1146079&r1=1146078&r2=1146079&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 Wed Jul 13 14:53:08 2011 @@ -18,8 +18,19 @@ */ package org.apache.qpid.server.security; -import static org.apache.qpid.server.security.access.ObjectType.*; -import static org.apache.qpid.server.security.access.Operation.*; +import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE; +import static org.apache.qpid.server.security.access.ObjectType.METHOD; +import static org.apache.qpid.server.security.access.ObjectType.OBJECT; +import static org.apache.qpid.server.security.access.ObjectType.QUEUE; +import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST; +import static org.apache.qpid.server.security.access.Operation.ACCESS; +import static org.apache.qpid.server.security.access.Operation.BIND; +import static org.apache.qpid.server.security.access.Operation.CONSUME; +import static org.apache.qpid.server.security.access.Operation.CREATE; +import static org.apache.qpid.server.security.access.Operation.DELETE; +import static org.apache.qpid.server.security.access.Operation.PUBLISH; +import static org.apache.qpid.server.security.access.Operation.PURGE; +import static org.apache.qpid.server.security.access.Operation.UNBIND; import java.net.SocketAddress; import java.security.Principal; @@ -29,6 +40,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.security.auth.Subject; + import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; @@ -37,11 +50,9 @@ import org.apache.qpid.server.configurat import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.Operation; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; /** * The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based @@ -55,7 +66,7 @@ public class SecurityManager private static final Logger _logger = Logger.getLogger(SecurityManager.class); /** Container for the {@link Principal} that is using to this thread. */ - private static final ThreadLocal<Principal> _principal = new ThreadLocal<Principal>(); + private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>(); private PluginManager _pluginManager; private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>(); @@ -126,19 +137,14 @@ public class SecurityManager configureHostPlugins(configuration); } - public static Principal getThreadPrincipal() - { - return _principal.get(); - } - - public static void setThreadPrincipal(Principal principal) + public static Subject getThreadSubject() { - _principal.set(principal); + return _subject.get(); } - public static void setThreadPrincipal(String authId) + public static void setThreadSubject(final Subject subject) { - setThreadPrincipal(new UsernamePrincipal(authId)); + _subject.set(subject); } public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java Wed Jul 13 14:53:08 2011 @@ -149,9 +149,9 @@ public class ObjectProperties extends Ha { put(Property.OWNER, queue.getOwner()); } - else if (queue.getPrincipalHolder() != null) + else if (queue.getAuthorizationHolder() != null) { - put(Property.OWNER, queue.getPrincipalHolder().getPrincipal().getName()); + put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName()); } } Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java?rev=1146079&view=auto ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java (added) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java Wed Jul 13 14:53:08 2011 @@ -0,0 +1,99 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.sasl; + +import java.security.Principal; +import java.security.acl.Group; +import java.util.Enumeration; + +/** + * Immutable representation of a user group. In Qpid, groups do <b>not</b> know + * about their membership, and therefore the {@link #addMember(Principal)} + * methods etc throw {@link UnsupportedOperationException}. + * + */ +public class GroupPrincipal implements Group +{ + /** Name of the group */ + private final String _groupName; + + public GroupPrincipal(final String groupName) + { + _groupName = groupName; + } + + public String getName() + { + return _groupName; + } + + public boolean addMember(Principal user) + { + throw new UnsupportedOperationException("Not supported"); + } + + public boolean removeMember(Principal user) + { + throw new UnsupportedOperationException("Not supported"); + } + + public boolean isMember(Principal member) + { + throw new UnsupportedOperationException("Not supported"); + } + + public Enumeration<? extends Principal> members() + { + throw new UnsupportedOperationException("Not supported"); + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() + { + final int prime = 37; + return prime * _groupName.hashCode(); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + else + { + if (obj instanceof GroupPrincipal) + { + GroupPrincipal other = (GroupPrincipal) obj; + return _groupName.equals(other._groupName); + } + else + { + return false; + } + } + } +} Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java Wed Jul 13 14:53:08 2011 @@ -259,7 +259,7 @@ public class AMQStateManager implements public AMQProtocolSession getProtocolSession() { - SecurityManager.setThreadPrincipal(_protocolSession.getPrincipal()); + SecurityManager.setThreadSubject(_protocolSession.getAuthorizedSubject()); return _protocolSession; } } Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java Wed Jul 13 14:53:08 2011 @@ -22,12 +22,15 @@ package org.apache.qpid.server.transport import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.*; +import java.security.Principal; import java.text.MessageFormat; import java.util.concurrent.atomic.AtomicBoolean; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import javax.security.auth.Subject; + import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.configuration.ConnectionConfig; @@ -38,7 +41,8 @@ import org.apache.qpid.server.logging.ac import org.apache.qpid.server.logging.messages.ConnectionMessages; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.AuthorizationHolder; +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Connection; @@ -49,14 +53,15 @@ import org.apache.qpid.transport.Method; import org.apache.qpid.transport.ProtocolEvent; import org.apache.qpid.transport.Session; -public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject +public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder { private ConnectionConfig _config; private Runnable _onOpenTask; private AtomicBoolean _logClosed = new AtomicBoolean(false); private LogActor _actor = GenericActor.getInstance(this); - private ApplicationRegistry _registry; + private Subject _authorizedSubject = null; + private Principal _authorizedPrincipal = null; private boolean _statisticsEnabled = false; private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; @@ -212,9 +217,9 @@ public class ServerConnection extends Co public String toLogString() { boolean hasVirtualHost = (null != this.getVirtualHost()); - boolean hasPrincipal = (null != getAuthorizationID()); + boolean hasClientId = (null != getClientId()); - if (hasPrincipal && hasVirtualHost) + if (hasClientId && hasVirtualHost) { return "[" + MessageFormat.format(CONNECTION_FORMAT, @@ -224,7 +229,7 @@ public class ServerConnection extends Co getVirtualHost().getName()) + "] "; } - else if (hasPrincipal) + else if (hasClientId) { return "[" + MessageFormat.format(USER_FORMAT, @@ -341,4 +346,37 @@ public class ServerConnection extends Co { _statisticsEnabled = enabled; } + + /** + * @return authorizedSubject + */ + public Subject getAuthorizedSubject() + { + return _authorizedSubject; + } + + /** + * Sets the authorized subject. It also extracts the UsernamePrincipal from the subject + * and caches it for optimisation purposes. + * + * @param authorizedSubject + */ + public void setAuthorizedSubject(final Subject authorizedSubject) + { + if (authorizedSubject == null) + { + _authorizedSubject = null; + _authorizedPrincipal = null; + } + else + { + _authorizedSubject = authorizedSubject; + _authorizedPrincipal = UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject); + } + } + + public Principal getAuthorizedPrincipal() + { + return _authorizedPrincipal; + } } Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java Wed Jul 13 14:53:08 2011 @@ -34,6 +34,8 @@ import org.apache.qpid.protocol.Protocol 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.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.*; @@ -70,7 +72,6 @@ public class ServerConnectionDelegate ex return list; } - @Override public ServerSession getSession(Connection conn, SessionAttach atc) { SessionDelegate serverSessionDelegate = new ServerSessionDelegate(_appRegistry); @@ -80,14 +81,33 @@ public class ServerConnectionDelegate ex return ssn; } - @Override protected SaslServer createSaslServer(String mechanism) throws SaslException { return _appRegistry.getAuthenticationManager().createSaslServer(mechanism, _localFQDN); } - @Override + protected void secure(final SaslServer ss, final Connection conn, final byte[] response) + { + final AuthenticationResult authResult = _appRegistry.getAuthenticationManager().authenticate(ss, response); + final ServerConnection sconn = (ServerConnection) conn; + + + if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus())) + { + tuneAuthorizedConnection(sconn); + sconn.setAuthorizedSubject(authResult.getSubject()); + } + else if (AuthenticationStatus.CONTINUE.equals(authResult.getStatus())) + { + connectionAuthContinue(sconn, authResult.getChallenge()); + } + else + { + connectionAuthFailed(sconn, authResult.getCause()); + } + } + public void connectionClose(Connection conn, ConnectionClose close) { try @@ -101,10 +121,9 @@ public class ServerConnectionDelegate ex } - @Override public void connectionOpen(Connection conn, ConnectionOpen open) { - ServerConnection sconn = (ServerConnection) conn; + final ServerConnection sconn = (ServerConnection) conn; VirtualHost vhost; String vhostName; @@ -118,7 +137,7 @@ public class ServerConnectionDelegate ex } vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName); - SecurityManager.setThreadPrincipal(conn.getAuthorizationID()); + SecurityManager.setThreadSubject(sconn.getAuthorizedSubject()); if(vhost != null) { Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java Wed Jul 13 14:53:08 2011 @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.transport; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.*; -import static org.apache.qpid.util.Serial.*; +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT; +import static org.apache.qpid.util.Serial.gt; import java.lang.ref.WeakReference; import java.security.Principal; @@ -38,6 +38,8 @@ import java.util.concurrent.ConcurrentSk import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; +import javax.security.auth.Subject; + import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.ProtocolEngine; @@ -57,7 +59,7 @@ import org.apache.qpid.server.protocol.A import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.security.PrincipalHolder; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.subscription.Subscription_0_10; import org.apache.qpid.server.txn.AutoCommitTransaction; @@ -75,9 +77,7 @@ import org.apache.qpid.transport.Session import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.security.auth.UserPrincipal; - -public class ServerSession extends Session implements PrincipalHolder, SessionConfig, AMQSessionModel, LogSubject +public class ServerSession extends Session implements AuthorizationHolder, SessionConfig, AMQSessionModel, LogSubject { private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class); @@ -118,8 +118,6 @@ public class ServerSession extends Sessi private final AtomicLong _txnCount = new AtomicLong(0); private final AtomicLong _txnUpdateTime = new AtomicLong(0); - private Principal _principal; - private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>(); private final List<Task> _taskList = new CopyOnWriteArrayList<Task>(); @@ -146,7 +144,7 @@ public class ServerSession extends Sessi super(connection, delegate, name, expiry); _connectionConfig = connConfig; _transaction = new AutoCommitTransaction(this.getMessageStore()); - _principal = new UserPrincipal(connection.getAuthorizationID()); + _reference = new WeakReference<Session>(this); _id = getConfigStore().createId(); getConfigStore().addConfiguredObject(this); @@ -419,7 +417,7 @@ public class ServerSession extends Sessi catch (AMQException e) { // TODO - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + _logger.error("Failed to unregister subscription", e); } finally { @@ -516,9 +514,14 @@ public class ServerSession extends Sessi return _txnCount.get(); } - public Principal getPrincipal() + public Principal getAuthorizedPrincipal() + { + return ((ServerConnection) getConnection()).getAuthorizedPrincipal(); + } + + public Subject getAuthorizedSubject() { - return _principal; + return ((ServerConnection) getConnection()).getAuthorizedSubject(); } public void addSessionCloseTask(Task task) Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java (original) +++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java Wed Jul 13 14:53:08 2011 @@ -27,19 +27,20 @@ import java.util.Map; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUnknownExchangeType; -import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.exchange.*; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.exchange.ExchangeFactory; +import org.apache.qpid.server.exchange.ExchangeInUseException; +import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.server.exchange.ExchangeType; +import org.apache.qpid.server.exchange.HeadersExchange; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; import org.apache.qpid.server.flow.FlowCreditManager_0_10; import org.apache.qpid.server.flow.WindowCreditManager; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.GenericActor; import org.apache.qpid.server.message.MessageMetaData_0_10; import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.BaseQueue; @@ -105,7 +106,8 @@ public class ServerSessionDelegate exten @Override public void command(Session session, Method method) { - SecurityManager.setThreadPrincipal(session.getConnection().getAuthorizationID()); + final ServerConnection scon = (ServerConnection) session.getConnection(); + SecurityManager.setThreadSubject(scon.getAuthorizedSubject()); if(!session.isClosing()) { @@ -203,7 +205,7 @@ public class ServerSessionDelegate exten { exception(session,method,ExecutionErrorCode.NOT_FOUND, "Queue: " + queueName + " not found"); } - else if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session) + else if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session) { exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); } @@ -213,17 +215,17 @@ public class ServerSessionDelegate exten { ServerSession s = (ServerSession) session; queue.setExclusiveOwningSession(s); - if(queue.getPrincipalHolder() == null) + if(queue.getAuthorizationHolder() == null) { - queue.setPrincipalHolder(s); + queue.setAuthorizationHolder(s); queue.setExclusiveOwningSession(s); ((ServerSession) session).addSessionCloseTask(new ServerSession.Task() { public void doTask(ServerSession session) { - if(queue.getPrincipalHolder() == session) + if(queue.getAuthorizationHolder() == session) { - queue.setPrincipalHolder(null); + queue.setAuthorizationHolder(null); queue.setExclusiveOwningSession(null); } } @@ -389,7 +391,7 @@ public class ServerSessionDelegate exten ((ServerSession)session).unregister(sub); if(!queue.isDeleted() && queue.isExclusive() && queue.getConsumerCount() == 0) { - queue.setPrincipalHolder(null); + queue.setAuthorizationHolder(null); } } } @@ -1007,7 +1009,7 @@ public class ServerSessionDelegate exten { public void doTask(ServerSession session) { - q.setPrincipalHolder(null); + q.setAuthorizationHolder(null); q.setExclusiveOwningSession(null); } }; @@ -1077,7 +1079,7 @@ public class ServerSessionDelegate exten } else { - if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session) + if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session) { exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); } Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java (original) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java Wed Jul 13 14:53:08 2011 @@ -28,11 +28,7 @@ import org.apache.qpid.server.logging.Ab public class UnitTestMessageLogger extends AbstractRootMessageLogger { - List<Object> _log; - - { - _log = new LinkedList<Object>(); - } + private final List<Object> _log = new LinkedList<Object>(); public UnitTestMessageLogger() { @@ -69,4 +65,14 @@ public class UnitTestMessageLogger exten { _log.clear(); } + + public boolean messageContains(final int index, final String contains) + { + if (index + 1 > _log.size()) + { + throw new IllegalArgumentException("Message with index " + index + " has not been logged"); + } + final String message = _log.get(index).toString(); + return message.contains(contains); + } } Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java (original) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java Wed Jul 13 14:53:08 2011 @@ -22,12 +22,15 @@ package org.apache.qpid.server.protocol; import java.security.Principal; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import javax.security.auth.Subject; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentHeaderBody; @@ -39,6 +42,8 @@ import org.apache.qpid.server.message.Me import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TestNetworkConnection; @@ -55,13 +60,8 @@ public class InternalTestProtocolSession _channelDelivers = new HashMap<Integer, Map<AMQShortString, LinkedList<DeliveryPair>>>(); // Need to authenticate session for it to be representative testing. - setAuthorizedID(new Principal() - { - public String getName() - { - return "InternalTestProtocolSession"; - } - }); + setAuthorizedSubject(new Subject(true, Collections.singleton(new UsernamePrincipal("InternalTestProtocolSession")), + Collections.EMPTY_SET, Collections.EMPTY_SET)); setVirtualHost(virtualHost); } Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java (original) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java Wed Jul 13 14:53:08 2011 @@ -29,7 +29,7 @@ import org.apache.qpid.server.subscripti import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.security.PrincipalHolder; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.binding.Binding; @@ -48,7 +48,7 @@ public class MockAMQQueue implements AMQ private AMQShortString _name; private VirtualHost _virtualhost; - private PrincipalHolder _principalHolder; + private AuthorizationHolder _authorizationHolder; private AMQSessionModel _exclusiveOwner; private AMQShortString _owner; @@ -536,14 +536,14 @@ public class MockAMQQueue implements AMQ return null; //To change body of implemented methods use File | Settings | File Templates. } - public PrincipalHolder getPrincipalHolder() + public AuthorizationHolder getAuthorizationHolder() { - return _principalHolder; + return _authorizationHolder; } - public void setPrincipalHolder(PrincipalHolder principalHolder) + public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder) { - _principalHolder = principalHolder; + _authorizationHolder = authorizationHolder; } public AMQSessionModel getExclusiveOwningSession() Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java?rev=1146079&view=auto ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java (added) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java Wed Jul 13 14:53:08 2011 @@ -0,0 +1,86 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.sasl; + +import junit.framework.TestCase; + +public class GroupPrincipalTest extends TestCase +{ + public void testGetName() + { + final GroupPrincipal principal = new GroupPrincipal("group"); + assertEquals("group", principal.getName()); + } + + public void testAddRejected() + { + final GroupPrincipal principal = new GroupPrincipal("group"); + final UsernamePrincipal user = new UsernamePrincipal("name"); + + try + { + principal.addMember(user); + fail("Exception not thrown"); + } + catch (UnsupportedOperationException uso) + { + // PASS + } + } + + public void testEqualitySameName() + { + final String string = "string"; + final GroupPrincipal principal1 = new GroupPrincipal(string); + final GroupPrincipal principal2 = new GroupPrincipal(string); + assertTrue(principal1.equals(principal2)); + } + + public void testEqualityEqualName() + { + final GroupPrincipal principal1 = new GroupPrincipal(new String("string")); + final GroupPrincipal principal2 = new GroupPrincipal(new String("string")); + assertTrue(principal1.equals(principal2)); + } + + public void testInequalityDifferentGroupPrincipals() + { + GroupPrincipal principal1 = new GroupPrincipal("string1"); + GroupPrincipal principal2 = new GroupPrincipal("string2"); + assertFalse(principal1.equals(principal2)); + } + + public void testInequalityNonGroupPrincipal() + { + GroupPrincipal principal = new GroupPrincipal("string"); + assertFalse(principal.equals(new UsernamePrincipal("string"))); + } + + public void testInequalityNull() + { + GroupPrincipal principal = new GroupPrincipal("string"); + assertFalse(principal.equals(null)); + } + + + + +} Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java?rev=1146079&view=auto ============================================================================== --- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java (added) +++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java Wed Jul 13 14:53:08 2011 @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.sasl; + +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.security.auth.Subject; + +public class TestPrincipalUtils +{ + + /** + * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals. + */ + public static Subject createTestSubject(final String username, final String... groups) + { + final Set<Principal> principals = new HashSet<Principal>(1 + groups.length); + principals.add(new UsernamePrincipal(username)); + for (String group : groups) + { + principals.add(new GroupPrincipal(group)); + } + + final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET); + return subject; + } + +} Modified: qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java (original) +++ qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java Wed Jul 13 14:53:08 2011 @@ -120,7 +120,6 @@ public class Connection extends Connecti private SaslServer saslServer; private SaslClient saslClient; private int idleTimeout = 0; - private String _authorizationID; private Map<String,Object> _serverProperties; private String userID; private ConnectionSettings conSettings; @@ -661,16 +660,6 @@ public class Connection extends Connecti return idleTimeout; } - public void setAuthorizationID(String authorizationID) - { - _authorizationID = authorizationID; - } - - public String getAuthorizationID() - { - return _authorizationID; - } - public String getUserID() { return userID; Modified: qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java?rev=1146079&r1=1146078&r2=1146079&view=diff ============================================================================== --- qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java (original) +++ qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java Wed Jul 13 14:53:08 2011 @@ -75,10 +75,7 @@ public class ServerDelegate extends Conn if (mechanism == null || mechanism.length() == 0) { - conn.connectionTune - (getChannelMax(), - org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE, - 0, getHeartbeatMax()); + tuneAuthorizedConnection(conn); return; } @@ -97,8 +94,7 @@ public class ServerDelegate extends Conn } catch (SaslException e) { - conn.exception(e); - conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage()); + connectionAuthFailed(conn, e); } } @@ -109,33 +105,52 @@ public class ServerDelegate extends Conn return ss; } - private void secure(Connection conn, byte[] response) + protected void secure(final SaslServer ss, final Connection conn, final byte[] response) { - SaslServer ss = conn.getSaslServer(); try { byte[] challenge = ss.evaluateResponse(response); if (ss.isComplete()) { ss.dispose(); - conn.connectionTune - (getChannelMax(), - org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE, - 0, getHeartbeatMax()); - conn.setAuthorizationID(ss.getAuthorizationID()); + tuneAuthorizedConnection(conn); } else { - conn.connectionSecure(challenge); + connectionAuthContinue(conn, challenge); } } catch (SaslException e) { - conn.exception(e); - conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage()); + connectionAuthFailed(conn, e); } } + protected void connectionAuthFailed(final Connection conn, Exception e) + { + conn.exception(e); + conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage()); + } + + protected void connectionAuthContinue(final Connection conn, byte[] challenge) + { + conn.connectionSecure(challenge); + } + + protected void tuneAuthorizedConnection(final Connection conn) + { + conn.connectionTune + (getChannelMax(), + org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE, + 0, getHeartbeatMax()); + } + + protected void secure(final Connection conn, final byte[] response) + { + final SaslServer ss = conn.getSaslServer(); + secure(ss, conn, response); + } + protected int getHeartbeatMax() { return 0xFFFF; --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:[email protected]
