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 2011/08/29 14:03:36 UTC

svn commit: r1162755 - in /activemq/activemq-apollo/trunk: apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/ apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/security/ apollo-openwire/src/main/scala/org/apache/activemq/apoll...

Author: chirino
Date: Mon Aug 29 12:03:36 2011
New Revision: 1162755

URL: http://svn.apache.org/viewvc?rev=1162755&view=rev
Log:
Fixes https://issues.apache.org/jira/browse/APLO-84 : Log more information in case of authorization failures

Modified:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/LocalRouter.scala
    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-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/scala/org/apache/activemq/apollo/stomp/StompTest.scala
    activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/LocalRouter.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/LocalRouter.scala?rev=1162755&r1=1162754&r2=1162755&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/LocalRouter.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/LocalRouter.scala Mon Aug 29 12:03:36 2011
@@ -271,24 +271,21 @@ class LocalRouter(val virtual_host:Virtu
         return None
       }
 
-      if( destination.temp_owner != null ) {
-        for( connection <- security.connection_id) {
-          if( connection != destination.temp_owner.longValue() ) {
-            return Some("Not authorized to destroy the destination.")
+      for(dest <- get_destination_matches(path)) {
+
+        if( destination.temp_owner != null ) {
+          for( connection <- security.connection_id) {
+            if( connection != destination.temp_owner.longValue() ) {
+              return Some("Not authorized to destroy the temp %s '%s'. Principals=%s".format(dest.resource_kind.id, dest.id, security.principal_dump))
+            }
           }
         }
-      }
 
-      val matches = get_destination_matches(path)
-      matches.foldLeft(None:Option[String]) { case (rc,dest) =>
-        rc.orElse {
-          if( authorizer.can(security, "destroy", dest) ) {
-            None
-          } else {
-            Some("Not authorized to destroy destination: %s".format(dest.id))
-          }
+        if( !authorizer.can(security, "destroy", dest) ) {
+          return Some("Not authorized to destroy the %s '%s'. Principals=%s".format(dest.resource_kind.id, dest.id, security.principal_dump))
         }
       }
+      None
     }
     def destroy_destination(path:Path, destination:DestinationDTO, security: SecurityContext):Unit
 
@@ -303,7 +300,7 @@ class LocalRouter(val virtual_host:Virtu
       if( destination.temp_owner != null ) {
         for( connection <- security.connection_id) {
           if( connection != destination.temp_owner.longValue() ) {
-            return Some("Not authorized to receive from the temporary destination.")
+            return Some("Not authorized to receive from the temporary destination. Principals=%s".format(security.principal_dump))
           }
         }
       }
@@ -325,8 +322,9 @@ class LocalRouter(val virtual_host:Virtu
         }
 
         matches.foreach { dest =>
-          if( !authorizer.can(security, bind_action(consumer), dest) ) {
-            return Some("Not authorized to receive from the destination.")
+          var action: String = bind_action(consumer)
+          if (!authorizer.can(security, action, dest)) {
+            return Some("Not authorized to %s from the %s '%s'. Principals=%s".format(action, dest.resource_kind.id, dest.id, security.principal_dump))
           }
         }
       }
@@ -390,7 +388,7 @@ class LocalRouter(val virtual_host:Virtu
         assert( matches.size == 1 )
         for( dest <- matches ) {
           if( !authorizer.can(security, "send", dest) ) {
-            return Some("Not authorized to send to the destination.")
+            return Some("Not authorized to send to the %s '%s'. Principals=%s".format(dest.resource_kind.id, dest.id, security.principal_dump))
           }
         }
 
@@ -533,7 +531,7 @@ class LocalRouter(val virtual_host:Virtu
         def id = destination_parser.encode_path(path)
       }
       if( !authorizer.can(security, "create", resource)) {
-        Some("Not authorized to create the destination")
+        return Some("Not authorized to create the topic '%s'. Principals=%s".format(resource.id, security.principal_dump))
       } else {
         None
       }
@@ -551,7 +549,7 @@ class LocalRouter(val virtual_host:Virtu
         def id = destination_parser.encode_path(path)
       }
       if( !authorizer.can(security, "create", resource)) {
-        return new Failure("Not authorized to create the destination")
+        return Failure("Not authorized to create the topic '%s'. Principals=%s".format(resource.id, security.principal_dump))
       }
 
       val topic = new Topic(LocalRouter.this, destination.asInstanceOf[TopicDestinationDTO], ()=>topic_config(path), path.toString(destination_parser), path)
@@ -715,7 +713,7 @@ class LocalRouter(val virtual_host:Virtu
     def can_create_dsub(config:DurableSubscriptionDTO, security:SecurityContext) = {
       val resource = get_dsub_secured_resource(config)
       if( !authorizer.can(security, "create", resource) ) {
-        Some("Not authorized to create the durable subscription.")
+        Some("Not authorized to create the durable subscription '%s'. Principals=%s".format(resource.id, security.principal_dump))
       } else {
         None
       }
@@ -724,7 +722,7 @@ class LocalRouter(val virtual_host:Virtu
     def can_connect_dsub(config:DurableSubscriptionDTO, security:SecurityContext):Option[String] = {
       val resource = get_dsub_secured_resource(config)
       if( !authorizer.can(security, "send", resource) ) {
-        Some("Not authorized to send to the durable subscription.")
+        Some("Not authorized to send to durable subscription '%s'. Principals=%s".format(resource.id, security.principal_dump))
       } else {
         None
       }
@@ -734,7 +732,7 @@ class LocalRouter(val virtual_host:Virtu
       val resource = get_dsub_secured_resource(config)
       val action = if ( consumer.browser ) "receive" else "consume"
       if( !authorizer.can(security, action, resource) ) {
-        Some("Not authorized to "+action+" from the durable subscription.")
+        Some("Not authorized to %s from durable subscription '%s'. Principals=%s".format(action, resource.id, security.principal_dump))
       } else {
         None
       }
@@ -788,7 +786,7 @@ class LocalRouter(val virtual_host:Virtu
       if( authorizer.can(security, "create", resource)) {
         None
       } else {
-        Some("Not authorized to create the queue")
+        Some("Not authorized to create the queue '%s'. Principals=%s".format(resource.id, security.principal_dump))
       }
     }
 
@@ -808,7 +806,7 @@ class LocalRouter(val virtual_host:Virtu
         }
         Success(queue)
       } else {
-        Failure("Not authorized to create the queue")
+        Failure("Not authorized to create the queue '%s'. Principals=%s".format(resource.id, security.principal_dump))
       }
 
     }
@@ -1175,7 +1173,7 @@ class LocalRouter(val virtual_host:Virtu
 
   def _destroy_queue(queue:Queue, security:SecurityContext):Option[String] = {
     if( !authorizer.can(security, "destroy", queue) ) {
-      return Some("Not authorized to destroy")
+      return Some("Not authorized to destroy queue '%s'. Principals=%s".format(queue.id, security.principal_dump))
     }
     _destroy_queue(queue)
     None

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=1162755&r1=1162754&r2=1162755&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 Mon Aug 29 12:03:36 2011
@@ -205,9 +205,9 @@ object Authorizer {
           ((ctx:SecurityContext) => {
             principal_kinds match {
               case Some(principal_kinds)=>
-                ctx.principles.find(p=> principal_kinds.contains(p.getClass.getName) ).isDefined
+                ctx.principals.find(p=> principal_kinds.contains(p.getClass.getName) ).isDefined
               case None =>
-                !ctx.principles.isEmpty
+                !ctx.principals.isEmpty
             }
           })
         case principal =>
@@ -219,13 +219,13 @@ object Authorizer {
           ((ctx:SecurityContext) => {
             principal_kinds match {
               case Some(principal_kinds)=>
-                ctx.principles.find{ p=>
+                ctx.principals.find{ p=>
                   val km = principal_kinds.contains(p.getClass.getName)
                   val nm = principals.contains(p.getName)
                   km && nm
                 }.isDefined
               case None =>
-                ctx.principles.find(p=> principals.contains(p.getName) ).isDefined
+                ctx.principals.find(p=> principals.contains(p.getName) ).isDefined
             }
           })
       })

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=1162755&r1=1162754&r2=1162755&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 Mon Aug 29 12:03:36 2011
@@ -41,30 +41,53 @@ class SecurityContext {
   var login_context:LoginContext = _
   var connection_id:Option[Long] = None
 
+  def credential_dump = {
+    var rc = List[String]()
+    if(certificates!=null) {
+      for(cert<-certificates) {
+        rc ::= "certdn="+cert.getSubjectX500Principal.getName
+      }
+    }
+    if(user!=null) {
+      rc ::= "user="+user
+    }
+    "["+rc.mkString(", ")+"]"
+  }
+
+  def principal_dump = {
+    var rc = List[String]()
+    if(_principals!=null) {
+      for(principal<-_principals) {
+        rc ::= principal.getClass.getName+":"+principal.getName
+      }
+    }
+    "["+rc.mkString(", ")+"]"
+  }
+
   private var _subject:Subject = _
 
   def subject = _subject
 
-  private var _principles = Set[Principal]()
-  def principles = _principles
+  private var _principals = Set[Principal]()
+  def principals = _principals
 
   def subject_= (value:Subject) {
     _subject = value
-    _principles = Set()
+    _principals = Set()
     if( value!=null ) {
       import collection.JavaConversions._
-      _principles = value.getPrincipals.toSet
+      _principals = value.getPrincipals.toSet
     }
   }
 
-  def principles(kind:String):Set[Principal] = {
+  def principals(kind:String):Set[Principal] = {
     kind match {
       case "+"=>
-        principles
+        principals
       case "*"=>
-        principles
+        principals
       case kind=>
-        principles.filter(_.getClass.getName == kind)
+        principals.filter(_.getClass.getName == kind)
     }
   }
 

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=1162755&r1=1162754&r2=1162755&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 Mon Aug 29 12:03:36 2011
@@ -435,11 +435,14 @@ class OpenwireProtocolHandler extends Pr
         if( host.authenticator!=null &&  host.authorizer!=null ) {
           suspendRead("authenticating and authorizing connect")
           if( !host.authenticator.authenticate(security_context) ) {
-            async_die("Authentication failed.", info)
-            noop
+            async_die("Authentication failed. Credentials="+security_context.credential_dump)
+            noop // to make the cps compiler plugin happy.
           } else if( !host.authorizer.can(security_context, "connect", connection.connector) ) {
-            async_die("Connect not authorized.", info)
-            noop
+            async_die("Not authorized to connect to connector '%s'. Principals=".format(connection.connector.id, security_context.principal_dump))
+            noop // to make the cps compiler plugin happy.
+          } else if( !host.authorizer.can(security_context, "connect", this.host) ) {
+            async_die("Not authorized to connect to virtual host '%s'. Principals=".format(this.host.id, security_context.principal_dump))
+            noop // to make the cps compiler plugin happy.
           } else {
             resumeRead
             ack(info);

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=1162755&r1=1162754&r2=1162755&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 Mon Aug 29 12:03:36 2011
@@ -827,21 +827,13 @@ class StompProtocolHandler extends Proto
         if( host.authenticator!=null &&  host.authorizer!=null ) {
           suspendRead("authenticating and authorizing connect")
           if( !host.authenticator.authenticate(security_context) ) {
-            var msg = if( security_context.user==null ) {
-              "Authentication failed."
-            } else {
-              "Authentication failed. Username="+security_context.user
-            }
-            async_die(msg)
+            async_die("Authentication failed. Credentials="+security_context.credential_dump)
             noop // to make the cps compiler plugin happy.
           } else if( !host.authorizer.can(security_context, "connect", connection.connector) ) {
-
-            var msg = if( security_context.user==null ) {
-              "Connect not authorized."
-            } else {
-              "Connect not authorized. Username="+security_context.user
-            }
-            async_die(msg)
+            async_die("Not authorized to connect to connector '%s'. Principals=".format(connection.connector.id, security_context.principal_dump))
+            noop // to make the cps compiler plugin happy.
+          } else if( !host.authorizer.can(security_context, "connect", this.host) ) {
+            async_die("Not authorized to connect to virtual host '%s'. Principals=".format(this.host.id, security_context.principal_dump))
             noop // to make the cps compiler plugin happy.
           } else {
             resumeRead
@@ -960,7 +952,7 @@ class StompProtocolHandler extends Proto
       if( !config.add_user_headers.isEmpty ){
         import collection.JavaConversions._
         config.add_user_headers.foreach { h =>
-          val matches = security_context.principles(Option(h.kind).getOrElse("*"))
+          val matches = security_context.principals(Option(h.kind).getOrElse("*"))
           if( !matches.isEmpty ) {
             h.separator match {
               case null=>

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=1162755&r1=1162754&r2=1162755&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 Mon Aug 29 12:03:36 2011
@@ -1292,7 +1292,7 @@ class StompSecurityTest extends StompTes
       "login:can_not_connect\n" +
       "passcode:can_not_connect\n")
     frame should startWith("ERROR\n")
-    frame should include("message:Connect not authorized.")
+    frame should include("message:Not authorized to connect")
 
   }
 
@@ -1332,7 +1332,7 @@ class StompSecurityTest extends StompTes
 
     val frame = client.receive()
     frame should startWith("ERROR\n")
-    frame should include("message:Not authorized to create the queue\n")
+    frame should include("message:Not authorized to create the queue")
   }
 
   test("Send authorized but not create") {
@@ -1349,7 +1349,7 @@ class StompSecurityTest extends StompTes
 
     val frame = client.receive()
     frame should startWith("ERROR\n")
-    frame should include("message:Not authorized to create the queue\n")
+    frame should include("message:Not authorized to create the queue")
 
   }
 
@@ -1367,7 +1367,7 @@ class StompSecurityTest extends StompTes
 
     val frame = client.receive()
     frame should startWith("ERROR\n")
-    frame should include("message:Not authorized to create the queue\n")
+    frame should include("message:Not authorized to create the queue")
   }
 
   test("Send and create authorized") {
@@ -1418,7 +1418,7 @@ class StompSecurityTest extends StompTes
 
     val frame = client.receive()
     frame should startWith("ERROR\n")
-    frame should include("message:Not authorized to receive from the destination.\n")
+    frame should include("message:Not authorized to consume from the queue")
   }
 
 //  test("Consume authorized and JMSXUserID is set on message") {

Modified: activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala?rev=1162755&r1=1162754&r2=1162755&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala Mon Aug 29 12:03:36 2011
@@ -55,7 +55,7 @@ case class BrokerResource() extends Reso
       if(broker.authenticator!=null) {
         authenticate(broker.authenticator) { security_context =>
           if(security_context!=null) {
-            rc.set(Success(security_context.principles))
+            rc.set(Success(security_context.principals))
           } else {
             rc.set(Success(Set[Principal]()))
           }