You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2012/02/21 14:37:42 UTC
svn commit: r1291776 - in /activemq/activemq-apollo/trunk:
apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/
apollo-dto/src/main/java/org/apache/activemq/apollo/dto/
apollo-openwire/src/main/scala/org/apache/activemq/apollo/openw...
Author: chirino
Date: Tue Feb 21 13:37:42 2012
New Revision: 1291776
URL: http://svn.apache.org/viewvc?rev=1291776&view=rev
Log:
Fixes APLO-165 : Enhance the access control rules to allow matching against the connector the user is connected against.
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java
activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala
activemq/activemq-apollo/trunk/apollo-stomp/src/main/scala/org/apache/activemq/apollo/stomp/StompProtocolHandler.scala
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml
activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties
activemq/activemq-apollo/trunk/apollo-stomp/src/test/scala/org/apache/activemq/apollo/stomp/StompTest.scala
activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/Authorizer.scala Tue Feb 21 13:37:42 2012
@@ -196,13 +196,23 @@ object Authorizer {
case principal_kind => Some(principal_kind.split("\\s").map(_.trim()).toSet)
}
+ def connector_match(func:(SecurityContext)=>Boolean):(SecurityContext)=>Boolean = {
+ Option(rule.connector).getOrElse("*") match {
+ case "*" => func
+ case connector_id =>
+ (ctx:SecurityContext) => {
+ ctx.connector_id==connector_id && func(ctx)
+ }
+ }
+ }
+
def parse_principals(value:String): Option[(SecurityContext)=>Boolean] = {
Option(value).map(_.trim() match {
case "*" =>
- ((ctx:SecurityContext) => { true })
+ connector_match((ctx:SecurityContext) => { true })
case "+" =>
// user has to have at least one of the principle kinds
- ((ctx:SecurityContext) => {
+ connector_match((ctx:SecurityContext) => {
principal_kinds match {
case Some(principal_kinds)=>
ctx.principals.find(p=> principal_kinds.contains(p.getClass.getName) ).isDefined
@@ -216,7 +226,7 @@ object Authorizer {
} else {
Set(principal)
}
- ((ctx:SecurityContext) => {
+ connector_match((ctx:SecurityContext) => {
principal_kinds match {
case Some(principal_kinds)=>
ctx.principals.find{ p=>
Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/SecurityContext.scala Tue Feb 21 13:37:42 2012
@@ -36,6 +36,7 @@ class SecurityContext {
var password:String = _
var sso_token:String = _
var certificates:Array[X509Certificate] = _
+ var connector_id:String = _
var local_address:SocketAddress = _
var remote_address:SocketAddress = _
var login_context:LoginContext = _
Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/AccessRuleDTO.java Tue Feb 21 13:37:42 2012
@@ -87,6 +87,13 @@ public class AccessRuleDTO {
public String id;
/**
+ * The id of the connector the user must be connected on for the
+ * rule to match. You can use `*` to match all connectors. Defaults to `*`.
+ */
+ @XmlAttribute
+ public String connector;
+
+ /**
* A regular expression used to match the id of the resource.
*/
@XmlAttribute(name = "id_regex")
@@ -114,6 +121,8 @@ public class AccessRuleDTO {
return false;
if (separator != null ? !separator.equals(that.separator) : that.separator != null)
return false;
+ if (connector != null ? !connector.equals(that.connector) : that.connector != null)
+ return false;
return true;
}
@@ -128,6 +137,7 @@ public class AccessRuleDTO {
result = 31 * result + (kind != null ? kind.hashCode() : 0);
result = 31 * result + (id != null ? id.hashCode() : 0);
result = 31 * result + (id_regex != null ? id_regex.hashCode() : 0);
+ result = 31 * result + (connector != null ? connector.hashCode() : 0);
return result;
}
@@ -150,6 +160,7 @@ public class AccessRuleDTO {
attr("kind",kind)+
attr("id",kind)+
attr("id_regex",id_regex)+
+ attr("connector",connector)+
"/>";
}
}
Modified: activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-openwire/src/main/scala/org/apache/activemq/apollo/openwire/OpenwireProtocolHandler.scala Tue Feb 21 13:37:42 2012
@@ -194,6 +194,7 @@ class OpenwireProtocolHandler extends Pr
connection_log = connection.connector.broker.connection_log
security_context.local_address = connection.transport.getLocalAddress
security_context.remote_address = connection.transport.getRemoteAddress
+ security_context.connector_id = connection.connector.id
sink_manager = new SinkMux[Command]( connection.transport_sink.map {x=>
x.setCommandId(next_command_id)
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=1291776&r1=1291775&r2=1291776&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 Tue Feb 21 13:37:42 2012
@@ -856,6 +856,7 @@ class StompProtocolHandler extends Proto
security_context.remote_address = connection.transport.getRemoteAddress
security_context.user = get(headers, LOGIN).map(decode_header _).getOrElse(null)
security_context.password = get(headers, PASSCODE).map(decode_header _).getOrElse(null)
+ security_context.connector_id = connection.connector.id
val accept_versions = get(headers, ACCEPT_VERSION).getOrElse(V1_0).split(COMMA).map(_.ascii)
protocol_version = SUPPORTED_PROTOCOL_VERSIONS.find( v=> accept_versions.contains(v) ) match {
Modified: 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=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/apollo-stomp-secure.xml Tue Feb 21 13:37:42 2012
@@ -33,6 +33,10 @@
<access_rule allow="guest" action="connect"/>
<access_rule allow="guest" action="create destroy send receive consume" kind="topic queue dsub" id_regex="test.*"/>
+ <!-- only allow connects over the tcp2 connector -->
+ <access_rule allow="connector_restricted" action="connect" connector="tcp2"/>
+
+
<virtual_host id="default">
<host_name>localhost</host_name>
</virtual_host>
@@ -40,5 +44,7 @@
<connector id="tcp" bind="tcp://0.0.0.0:0">
<stomp add_user_header="JMSXUserID"/>
</connector>
+ <connector id="tcp2" bind="tcp://0.0.0.0:0">
+ </connector>
</broker>
\ No newline at end of file
Modified: 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=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties (original)
+++ activemq/activemq-apollo/trunk/apollo-stomp/src/test/resources/users.properties Tue Feb 21 13:37:42 2012
@@ -20,6 +20,7 @@ connect_group=CN=ssl_user|can_only_conne
guest=guest
can_not_connect=can_not_connect
can_only_connect=can_only_connect
+connector_restricted=connector_restricted
#
# Users with specific roles related to queues
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=1291776&r1=1291775&r2=1291776&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 Tue Feb 21 13:37:42 2012
@@ -59,8 +59,11 @@ class StompTestSupport extends FunSuiteS
clients = Nil
}
- def connect_request(version:String, c: StompClient, headers:String="") = {
- c.open("localhost", port)
+ def connect_request(version:String, c: StompClient, headers:String="", connector:String=null) = {
+ val p = Option(connector).map{ id =>
+ broker.connectors.get(id).map(_.socket_address.asInstanceOf[InetSocketAddress].getPort).getOrElse(port)
+ }.getOrElse(port)
+ c.open("localhost", p)
version match {
case "1.0"=>
c.write(
@@ -80,8 +83,8 @@ class StompTestSupport extends FunSuiteS
c.receive()
}
- def connect(version:String, c: StompClient = client, headers:String="") = {
- val frame = connect_request(version, c, headers)
+ def connect(version:String, c: StompClient = client, headers:String="", connector:String=null) = {
+ val frame = connect_request(version, c, headers, connector)
frame should startWith("CONNECTED\n")
frame should include regex("""session:.+?\n""")
frame should include("version:"+version+"\n")
@@ -1904,6 +1907,20 @@ class StompSecurityTest extends StompTes
}
+ test("Connector restricted user on the right connector") {
+ connect("1.1", client,
+ "login:connector_restricted\n" +
+ "passcode:connector_restricted\n", "tcp2")
+ }
+
+ test("Connector restricted user on the wrong connector") {
+ val frame = connect_request("1.1", client,
+ "login:connector_restricted\n" +
+ "passcode:connector_restricted\n", "tcp")
+ frame should startWith("ERROR\n")
+ frame should include("message:Not authorized to connect to connector 'tcp'.")
+ }
+
test("Send not authorized") {
connect("1.1", client,
"login:can_only_connect\n" +
Modified: activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md?rev=1291776&r1=1291775&r2=1291776&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md (original)
+++ activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md Tue Feb 21 13:37:42 2012
@@ -710,6 +710,9 @@ an authorization check:
* `id_regex`: A regular expression to be applied against the id of the
resource.
+* `connector`: The id of the connector the user must be connected on for the
+ rule to match. You can use `*` to match all connectors. Defaults to `*`.
+
If no access rules match an authorization check then access is denied.
##### Ordering