Author: chirino
Date: Sun Dec 12 04:50:58 2010
New Revision: 1044767
URL: http://svn.apache.org/viewvc?rev=1044767&view=rev
Log:
You can now extract the user id of the authenticated user
protocol configuration can now be customized per transport.
added a stomp option to set a header to the sender's user id.
Added:
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ProtocolDTO.java
- copied, changed from r1044766,
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/StompDTO.java
- copied, changed from r1044766,
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/log4j.properties
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/login.config
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Connector.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/VirtualHost.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/FileLoginModule.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticationDTO.java
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
activemq/activemq-apollo/trunk/apollo-dto/src/main/resources/org/apache/activemq/apollo/dto/jaxb.index
activemq/activemq-apollo/trunk/apollo-dto/src/test/java/org/apache/activemq/apollo/dto/XmlCodecTest.java
activemq/activemq-apollo/trunk/apollo-dto/src/test/resources/org/apache/activemq/apollo/dto/XmlCodecTest.xml
activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
Sun Dec 12 04:50:58 2010
@@ -218,8 +218,8 @@ class Broker() extends BaseService with
import OptionSupport._
if( config.authentication != null &&
config.authentication.enabled.getOrElse(true) ) {
- authenticator = new JaasAuthenticator(config.authentication.domain)
- authorizer = new AclAuthorizer(config.authentication.kinds().toList)
+ authenticator = new JaasAuthenticator(config.authentication)
+ authorizer = new
AclAuthorizer(config.authentication.acl_principal_kinds().toList)
}
default_virtual_host = null
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Connector.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Connector.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Connector.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Connector.scala
Sun Dec 12 04:50:58 2010
@@ -145,7 +145,7 @@ class Connector(val broker:Broker, val i
override def _start(onCompleted:Runnable) = {
assert(config!=null, "Connector must be configured before it is started.")
- protocol = ProtocolFactory.get(config.protocol).get
+ protocol = ProtocolFactory.get(config.protocol.getOrElse("multi")).get
transportServer = TransportFactory.bind( config.bind )
transportServer.setDispatchQueue(dispatchQueue)
transportServer.setAcceptListener(BrokerAcceptListener)
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/VirtualHost.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/VirtualHost.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/VirtualHost.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/VirtualHost.scala
Sun Dec 12 04:50:58 2010
@@ -119,8 +119,8 @@ class VirtualHost(val broker: Broker, va
if( config.authentication != null ) {
if( config.authentication.enabled.getOrElse(true) ) {
// Virtual host has it's own settings.
- authenticator = new JaasAuthenticator(config.authentication.domain)
- authorizer = new AclAuthorizer(config.authentication.kinds().toList)
+ authenticator = new JaasAuthenticator(config.authentication)
+ authorizer = new
AclAuthorizer(config.authentication.acl_principal_kinds().toList)
} else {
// Don't use security on this host.
authenticator = null
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
Sun Dec 12 04:50:58 2010
@@ -33,4 +33,9 @@ trait Authenticator {
*/
def authenticate(ctx:SecurityContext):Boolean @suspendable
+ /**
+ * Extracts the user name of the logged in user.
+ */
+ def user_name(ctx:SecurityContext):Option[String]
+
}
\ No newline at end of file
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/FileLoginModule.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/FileLoginModule.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/FileLoginModule.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/FileLoginModule.scala
Sun Dec 12 04:50:58 2010
@@ -132,13 +132,12 @@ class FileLoginModule extends LoginModul
principals.add(new UserPrincipal(user))
val en = groups.keys()
while (en.hasMoreElements()) {
- val name = en.nextElement().asInstanceOf[String]
- val userList = (groups.getProperty(name) + "").split(",")
- userList.foreach{
- x =>
- if (user == x) {
- principals.add(new GroupPrincipal(name))
- }
+ val group_name = en.nextElement().asInstanceOf[String]
+ val users = groups.getProperty(group_name).split(",").map(_.trim)
+ users.foreach { x =>
+ if (user == x) {
+ principals.add(new GroupPrincipal(group_name))
+ }
}
}
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/JaasAuthenticator.scala
Sun Dec 12 04:50:58 2010
@@ -28,6 +28,7 @@ import org.apache.activemq.jaas._
import org.apache.activemq.apollo.util.OptionSupport._
import org.apache.activemq.apollo.broker.Broker.BLOCKABLE_THREAD_POOL
import org.fusesource.hawtdispatch._
+import org.apache.activemq.apollo.dto.{PrincipalDTO, AuthenticationDTO}
/**
* <p>
@@ -36,7 +37,10 @@ import org.fusesource.hawtdispatch._
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
-class JaasAuthenticator(val jass_realm: String) extends Authenticator {
+class JaasAuthenticator(val config: AuthenticationDTO) extends Authenticator {
+
+ val jass_realm = config.domain.getOrElse("apollo")
+ val user_principal_kinds = config.user_principal_kinds()
/*
* The 'BLOCKABLE_THREAD_POOL ! { ... }' magic makes the code block
@@ -47,6 +51,18 @@ class JaasAuthenticator(val jass_realm:
_authenticate(security_ctx)
}
+ /**
+ * Extracts the user name of the logged in user.
+ */
+ def user_name(ctx:SecurityContext):Option[String] = {
+ if( ctx.subject!=null ) {
+ import collection.JavaConversions._
+ ctx.subject.getPrincipals.find( x=> user_principal_kinds.contains(
x.getClass.getName ) ).map(_.getName)
+ } else {
+ None
+ }
+ }
+
def _authenticate(security_ctx: SecurityContext): Boolean = {
val original = Thread.currentThread().getContextClassLoader()
Thread.currentThread().setContextClassLoader(getClass.getClassLoader())
Modified:
activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
Sun Dec 12 04:50:58 2010
@@ -140,7 +140,7 @@ class Run extends Action with Logging {
val security_handler = new ConstraintSecurityHandler
val login_service = new
JAASLoginService(config.authentication.domain)
- val role_class_names:List[String] =
config.authentication.kinds().toList
+ val role_class_names:List[String] =
config.authentication.acl_principal_kinds().toList
login_service.setRoleClassNames(role_class_names.toArray)
security_handler.setLoginService(login_service)
Modified:
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticationDTO.java
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticationDTO.java?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticationDTO.java
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AuthenticationDTO.java
Sun Dec 12 04:50:58 2010
@@ -21,9 +21,7 @@ import javax.xml.bind.annotation.XmlAcce
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* <p>
@@ -40,17 +38,35 @@ public class AuthenticationDTO {
@XmlAttribute
public String domain;
- @XmlElement(name="kind")
- public List<String> kinds = new ArrayList<String>();
+ /**
+ * The class names for the types of principles that
+ * the acl lists check against.
+ */
+ @XmlElement(name="acl-principal-kinds")
+ public List<String> acl_principal_kinds = new ArrayList<String>();
-
- public List<String> kinds() {
- if( kinds.isEmpty() ) {
+ public List<String> acl_principal_kinds() {
+ if( acl_principal_kinds.isEmpty() ) {
ArrayList<String> rc = new ArrayList<String>();
rc.add("org.apache.activemq.jaas.GroupPrincipal");
return rc;
}
- return kinds;
+ return acl_principal_kinds;
}
+ /**
+ * The class names for the types of principles that
+ * the user name is extracted from.
+ */
+ @XmlElement(name="user-principal-kinds")
+ public List<String> user_principal_kinds = new ArrayList<String>();
+
+ public List<String> user_principal_kinds() {
+ if( user_principal_kinds.isEmpty() ) {
+ ArrayList<String> rc = new ArrayList<String>();
+ rc.add("org.apache.activemq.jaas.UserPrincipal");
+ return rc;
+ }
+ return user_principal_kinds;
+ }
}
Modified:
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
Sun Dec 12 04:50:58 2010
@@ -16,10 +16,9 @@
*/
package org.apache.activemq.apollo.dto;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.*;
+import java.util.ArrayList;
+import java.util.List;
/**
*
@@ -52,5 +51,11 @@ public class ConnectorDTO extends Servic
@XmlAttribute(name="connection-limit")
public Integer connection_limit;
+ /**
+ * A broker accepts connections via it's configured connectors.
+ */
+ @XmlElementRef
+ public List<ProtocolDTO> protocols = new ArrayList<ProtocolDTO>();
+
}
\ No newline at end of file
Copied:
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ProtocolDTO.java
(from r1044766,
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala)
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ProtocolDTO.java?p2=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ProtocolDTO.java&p1=activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala&r1=1044766&r2=1044767&rev=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authenticator.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ProtocolDTO.java
Sun Dec 12 04:50:58 2010
@@ -14,23 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.activemq.apollo.broker.security
-import scala.util.continuations._
+package org.apache.activemq.apollo.dto;
+
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
/**
- * <p>
- * </p>
- *
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
-trait Authenticator {
-
- /**
- * If the authentication succeeds, then the subject and
- * principles fields of the SecurityContext should be populated.
- *
- * @returns true if the SecurityContext was authenticated.
- */
- def authenticate(ctx:SecurityContext):Boolean @suspendable
+...@jsontypeinfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY,
property="@class")
+public abstract class ProtocolDTO {
-}
\ No newline at end of file
+}
Copied:
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/StompDTO.java
(from r1044766,
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java)
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/StompDTO.java?p2=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/StompDTO.java&p1=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java&r1=1044766&r2=1044767&rev=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ConnectorDTO.java
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/StompDTO.java
Sun Dec 12 04:50:58 2010
@@ -22,35 +22,15 @@ import javax.xml.bind.annotation.XmlAttr
import javax.xml.bind.annotation.XmlRootElement;
/**
- *
- *
+ * Allow you to customize the stomp protocol implementation.
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
-...@xmlrootelement(name = "connector")
+...@xmlrootelement(name="stomp")
@XmlAccessorType(XmlAccessType.FIELD)
-public class ConnectorDTO extends ServiceDTO<String> {
-
- /**
- * The transport uri which it will accept connections on.
- */
- @XmlAttribute
- public String bind;
-
- /**
- * The protocol that the transport will use.
- */
- @XmlAttribute
- public String protocol;
-
- /**
- * The uri which will be advertised for remote endpoints to connect to.
- */
- @XmlAttribute
- public String advertise;
+public class StompDTO extends ProtocolDTO {
- @XmlAttribute(name="connection-limit")
- public Integer connection_limit;
+ @XmlAttribute(name = "add-user-header")
+ public String add_user_header;
-
-}
\ No newline at end of file
+}
Modified:
activemq/activemq-apollo/trunk/apollo-dto/src/main/resources/org/apache/activemq/apollo/dto/jaxb.index
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/resources/org/apache/activemq/apollo/dto/jaxb.index?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/main/resources/org/apache/activemq/apollo/dto/jaxb.index
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/main/resources/org/apache/activemq/apollo/dto/jaxb.index
Sun Dec 12 04:50:58 2010
@@ -45,3 +45,4 @@ QueueDTO
DestinationDTO
LinkDTO
QueueConsumerStatusDTO
+StompDTO
\ No newline at end of file
Modified:
activemq/activemq-apollo/trunk/apollo-dto/src/test/java/org/apache/activemq/apollo/dto/XmlCodecTest.java
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/test/java/org/apache/activemq/apollo/dto/XmlCodecTest.java?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/test/java/org/apache/activemq/apollo/dto/XmlCodecTest.java
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/test/java/org/apache/activemq/apollo/dto/XmlCodecTest.java
Sun Dec 12 04:50:58 2010
@@ -38,6 +38,14 @@ public class XmlCodecTest {
BrokerDTO dto =
XmlCodec.unmarshalBrokerDTO(resource("XmlCodecTest.xml"));
assertNotNull(dto);
assertEquals("default", dto.id);
+ assertEquals(1, dto.connectors.size());
+ ConnectorDTO connector = dto.connectors.get(0);
+ assertEquals(1, connector.protocols.size());
+ ProtocolDTO stomp = connector.protocols.get(0);
+ assertTrue(stomp instanceof StompDTO);
+ assertEquals("JMSXUserID", ((StompDTO) stomp).add_user_header);
+
+
VirtualHostDTO host = dto.virtual_hosts.get(0);
assertNotNull(host.acl);
assertEquals("vh-local", host.id);
Modified:
activemq/activemq-apollo/trunk/apollo-dto/src/test/resources/org/apache/activemq/apollo/dto/XmlCodecTest.xml
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/test/resources/org/apache/activemq/apollo/dto/XmlCodecTest.xml?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-dto/src/test/resources/org/apache/activemq/apollo/dto/XmlCodecTest.xml
(original)
+++
activemq/activemq-apollo/trunk/apollo-dto/src/test/resources/org/apache/activemq/apollo/dto/XmlCodecTest.xml
Sun Dec 12 04:50:58 2010
@@ -28,5 +28,7 @@
<host-name>localhost</host-name>
<host-name>example.com</host-name>
</virtual-host>
- <connector bind="tcp://0.0.0.0:61616" enabled="true" id="port-61616"/>
+ <connector bind="tcp://0.0.0.0:61616" enabled="true" id="port-61616">
+ <stomp add-user-header="JMSXUserID"/>
+ </connector>
</broker>
Modified:
activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
Sun Dec 12 04:50:58 2010
@@ -33,8 +33,8 @@ import org.apache.activemq.apollo.store.
import org.apache.activemq.apollo.util._
import java.util.concurrent.TimeUnit
import java.util.Map.Entry
-import org.apache.activemq.apollo.dto.{StompConnectionStatusDTO, BindingDTO,
SubscriptionBindingDTO, QueueBindingDTO}
import scala.util.continuations._
+import org.apache.activemq.apollo.dto._
object StompProtocolHandler extends Log {
@@ -165,6 +165,7 @@ class StompProtocolHandler extends Proto
val dispatchQueue = StompProtocolHandler.this.dispatchQueue
+
dispatchQueue.retain
setDisposer(^{
session_manager.release
@@ -250,7 +251,13 @@ class StompProtocolHandler extends Proto
var heart_beat_monitor:HeartBeatMonitor = new HeartBeatMonitor
val security_context = new SecurityContext
var waiting_on:String = "client request"
+ var config:StompDTO = _
+ override def setConnection(connection: BrokerConnection) = {
+ super.setConnection(connection)
+ import collection.JavaConversions._
+ config = connection.connector.config.protocols.find(
_.isInstanceOf[StompDTO]).map(_.asInstanceOf[StompDTO]).getOrElse(new StompDTO)
+ }
override def create_connection_status = {
var rc = new StompConnectionStatusDTO
@@ -595,10 +602,25 @@ class StompProtocolHandler extends Proto
var message_id_counter = 0;
- def next_message_id = {
- message_id_counter += 1
- // TODO: properly generate mesage ids
- new AsciiBuffer("msg:"+message_id_counter);
+
+ def updated_headers(headers:HeaderMap) = {
+ var rc:HeaderMap=Nil
+
+ // Do we need to add the message id?
+ if( get( headers, MESSAGE_ID) == None ) {
+ // TODO: properly generate mesage ids
+ message_id_counter += 1
+ rc ::= (MESSAGE_ID, ascii("msg:"+message_id_counter))
+ }
+
+ // Do we need to add the user id?
+ if( host.authenticator!=null && config.add_user_header!=null ) {
+ host.authenticator.user_name(security_context).foreach{ name=>
+ rc ::= (ascii(config.add_user_header), ascii(name))
+ }
+ }
+
+ rc
}
def send_via_route(route:DeliveryProducerRoute, frame:StompFrame,
uow:StoreUOW) = {
@@ -609,13 +631,11 @@ class StompProtocolHandler extends Proto
if( !route.targets.isEmpty ) {
// We may need to add some headers..
- var message = get( frame.headers, MESSAGE_ID) match {
- case None=>
- var updated_headers:HeaderMap=Nil;
- updated_headers ::= (MESSAGE_ID, next_message_id)
- StompFrameMessage(StompFrame(MESSAGE, frame.headers, frame.content,
updated_headers))
- case Some(id)=>
+ var message = updated_headers(frame.headers) match {
+ case Nil=>
StompFrameMessage(StompFrame(MESSAGE, frame.headers, frame.content))
+ case updated_headers =>
+ StompFrameMessage(StompFrame(MESSAGE, frame.headers, frame.content,
updated_headers))
}
val delivery = new Delivery
Added:
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml?rev=1044767&view=auto
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
(added)
+++
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
Sun Dec 12 04:50:58 2010
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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.
+-->
+<broker id="default" rev="1"
xmlns="http://activemq.apache.org/schema/activemq/apollo">
+
+ <authentication domain="StompSecurityTest"/>
+
+ <virtual-host id="default" purge-on-startup="true">
+ <host-name>localhost</host-name>
+
+ <acl>
+ <connect name="connect_group"/>
+ </acl>
+
+ <!-- queue security -->
+ <queue path="**" kind="ptp">
+ <acl>
+ <create name="can_send_create_queue"/>
+ <send name="can_send_create_queue"/>
+ <send name="can_send_queue"/>
+ <receive name="can_receive_queue"/>
+ <consume name="can_consume_queue"/>
+ </acl>
+ </queue>
+
+ <!-- topic security -->
+ <destination path="**">
+ <acl>
+ <create name="can_send_create_topic"/>
+ <send name="can_send_create_topic"/>
+ <send name="can_send_topic"/>
+ <receive name="can_recieve_topic"/>
+ </acl>
+ </destination>
+
+ <!-- durable sub security -->
+ <queue path="**" kind="ds">
+ <acl>
+ <create name="can_consume_create_ds"/>
+ <consume name="can_consume_create_ds"/>
+ <consume name="can_consume_ds"/>
+ </acl>
+ </queue>
+ </virtual-host>
+
+ <connector id="tcp" protocol="stomp" bind="tcp://0.0.0.0:0">
+ <stomp add-user-header="JMSXUserID"/>
+ </connector>
+
+</broker>
\ No newline at end of file
Added:
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/log4j.properties
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/log4j.properties?rev=1044767&view=auto
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/log4j.properties
(added)
+++
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/log4j.properties
Sun Dec 12 04:50:58 2010
@@ -0,0 +1,46 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+#
+# Setup the default logging levels
+#
+log4j.rootLogger=WARN, console, logfile
+log4j.logger.org.apache.activemq.apollo=INFO
+
+#
+# Uncomment one of the following to enable debug logging
+#
+# log4j.logger.org.apache.activemq.apollo=DEBUG
+# log4j.logger.org.apache.activemq.apollo.broker=DEBUG
+# log4j.logger.org.apache.activemq.apollo.web=DEBUG
+# log4j.logger.org.apache.activemq.apollo.cli=DEBUG
+# log4j.logger.org.apache.activemq.apollo.store.hawtdb=DEBUG
+
+# Console Settings
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-5p | %m%n
+log4j.appender.console.threshold=INFO
+
+# File Settings
+log4j.appender.logfile=org.apache.log4j.RollingFileAppender
+log4j.appender.logfile.file=${apollo.base}/log/apollo.log
+log4j.appender.logfile.maxFileSize=5MB
+log4j.appender.logfile.maxBackupIndex=5
+log4j.appender.logfile.append=true
+log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logfile.layout.ConversionPattern=%d | %-5p | %m | %c | %t%n
\ No newline at end of file
Added:
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/login.config
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/login.config?rev=1044767&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/login.config
(added)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/login.config
Sun Dec 12 04:50:58 2010
@@ -0,0 +1,29 @@
+// ---------------------------------------------------------------------------
+// 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.
+// ---------------------------------------------------------------------------
+StompSecurityTest {
+
+ //
+ // For testing purposes, we do a funny thing where we set the user
+ // file to also be used as the groups file. This only works for the
+ // test since user==password==group for our tests.
+ //
+ org.apache.activemq.apollo.broker.security.FileLoginModule required
+ users_file="users.properties"
+ groups_file="users.properties"
+ ;
+
+};
\ No newline at end of file
Added:
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties?rev=1044767&view=auto
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
(added)
+++
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
Sun Dec 12 04:50:58 2010
@@ -0,0 +1,39 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+connect_group=can_only_connect,can_send_create_queue,can_send_queue,can_receive_queue,can_consume_queue,can_send_create_topic,can_send_topic,can_recieve_topic,can_consume_create_ds,can_consume_ds
+
+can_not_connect=can_not_connect
+can_only_connect=can_only_connect
+
+#
+# Users with specific roles related to queues
+#
+can_send_create_queue=can_send_create_queue
+can_send_queue=can_send_queue
+can_receive_queue=can_receive_queue
+can_consume_queue=can_consume_queue
+
+#
+# Users with specific roles related to topics
+#
+can_send_create_topic=can_send_create_topic
+can_send_topic=can_send_topic
+can_recieve_topic=can_recieve_topic
+can_consume_create_ds=can_consume_create_ds
+can_consume_ds=can_consume_ds
+
Modified:
activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala?rev=1044767&r1=1044766&r2=1044767&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
Sun Dec 12 04:50:58 2010
@@ -49,26 +49,32 @@ class StompTestSupport extends FunSuiteS
clients = Nil
}
- def connect(version:String, c: StompClient = client) = {
+ def connect_request(version:String, c: StompClient, headers:String="") = {
c.open("localhost", port)
version match {
case "1.0"=>
c.write(
"CONNECT\n" +
+ headers +
"\n")
case "1.1"=>
c.write(
"CONNECT\n" +
"accept-version:1.1\n" +
"host:localhost\n" +
+ headers +
"\n")
case x=> throw new RuntimeException("invalid version: %f".format(x))
}
- val frame = c.receive()
+ clients ::= c
+ c.receive()
+ }
+
+ def connect(version:String, c: StompClient = client, headers:String="") = {
+ val frame = connect_request(version, c, headers)
frame should startWith("CONNECTED\n")
frame should include regex("""session:.+?\n""")
frame should include("version:"+version+"\n")
- clients ::= c
c
}
@@ -695,4 +701,172 @@ class StompAckModeTest extends StompTest
}
-}
\ No newline at end of file
+}
+
+class StompSecurityTest extends StompTestSupport {
+
+ override val broker_config_uri: String =
"xml:classpath:apollo-stomp-secure.xml"
+
+ override protected def beforeAll = {
+ try {
+ val login_file = new
java.io.File(getClass.getClassLoader.getResource("login.config").getFile())
+ System.setProperty("java.security.auth.login.config",
login_file.getCanonicalPath)
+ } catch {
+ case x:Throwable => x.printStackTrace
+ }
+ super.beforeAll
+ }
+
+ test("Connect with no id password") {
+ val frame = connect_request("1.1", client)
+ frame should startWith("ERROR\n")
+ frame should include("message:Authentication failed.\n")
+ }
+
+ test("Connect with invalid id password") {
+ val frame = connect_request("1.1", client,
+ "login:foo\n" +
+ "passcode:bar\n")
+ frame should startWith("ERROR\n")
+ frame should include("message:Authentication failed.\n")
+
+ }
+
+ test("Connect with valid id password but can't connect") {
+
+ val frame = connect_request("1.1", client,
+ "login:can_not_connect\n" +
+ "passcode:can_not_connect\n")
+ frame should startWith("ERROR\n")
+ frame should include("message:Connect not authorized.\n")
+
+ }
+
+ test("Connect with valid id password that can connect") {
+ connect("1.1", client,
+ "login:can_only_connect\n" +
+ "passcode:can_only_connect\n")
+
+ }
+
+ test("Send not authorized") {
+ connect("1.1", client,
+ "login:can_only_connect\n" +
+ "passcode:can_only_connect\n")
+
+ client.write(
+ "SEND\n" +
+ "destination:/queue/secure\n" +
+ "receipt:0\n" +
+ "\n" +
+ "Hello Wolrd\n")
+
+ val frame = client.receive()
+ frame should startWith("ERROR\n")
+ frame should include("message:Not authorized to send to the queue\n")
+ }
+
+ test("Send authorized but not create") {
+ connect("1.1", client,
+ "login:can_send_queue\n" +
+ "passcode:can_send_queue\n")
+
+ client.write(
+ "SEND\n" +
+ "destination:/queue/secure\n" +
+ "receipt:0\n" +
+ "\n" +
+ "Hello Wolrd\n")
+
+ val frame = client.receive()
+ frame should startWith("ERROR\n")
+ frame should include("message:Not authorized to create the queue\n")
+
+ }
+
+//
+// test("Consume authorized but not create") {
+// connect("1.1", client,
+// "login:can_consume_queue\n" +
+// "passcode:can_consume_queue\n")
+//
+// client.write(
+// "SUBSCRIBE\n" +
+// "destination:/queue/secure\n" +
+// "id:0\n" +
+// "receipt:0\n" +
+// "\n")
+// wait_for_receipt("0")
+//
+// val frame = client.receive()
+// frame should startWith("ERROR\n")
+// frame should include("message:Not authorized to create the queue\n")
+// }
+
+ test("Send and create authorized") {
+ connect("1.1", client,
+ "login:can_send_create_queue\n" +
+ "passcode:can_send_create_queue\n")
+
+ client.write(
+ "SEND\n" +
+ "destination:/queue/secure\n" +
+ "receipt:0\n" +
+ "\n" +
+ "Hello Wolrd\n")
+
+ wait_for_receipt("0")
+
+ }
+
+ test("Can send and once created") {
+
+ // Now try sending with the lower access id.
+ connect("1.1", client,
+ "login:can_send_queue\n" +
+ "passcode:can_send_queue\n")
+
+ client.write(
+ "SEND\n" +
+ "destination:/queue/secure\n" +
+ "receipt:0\n" +
+ "\n" +
+ "Hello Wolrd\n")
+
+ wait_for_receipt("0")
+
+ }
+
+ test("Consume not authorized") {
+ connect("1.1", client,
+ "login:can_only_connect\n" +
+ "passcode:can_only_connect\n")
+
+ client.write(
+ "SUBSCRIBE\n" +
+ "destination:/queue/secure\n" +
+ "id:0\n" +
+ "receipt:0\n" +
+ "\n")
+
+ val frame = client.receive()
+ frame should startWith("ERROR\n")
+ frame should include("message:Not authorized to consume from the queue\n")
+ }
+
+// test("Consume authorized and JMSXUserID is set on message") {
+// connect("1.1", client,
+// "login:can_consume_queue\n" +
+// "passcode:can_consume_queue\n")
+//
+// client.write(
+// "SUBSCRIBE\n" +
+// "destination:/queue/secure\n" +
+// "id:0\n" +
+// "\n")
+//
+// val frame = client.receive()
+// frame should startWith("MESSAGE\n")
+// frame should include("JMSXUserID:can_send_create_queue\n")
+// }
+}