[jboss-cvs] JBossAS SVN: r114607 - in branches/JBPAPP_5: testsuite/src/main/org/jboss/test/jmx/invoker and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Dec 18 03:20:35 EST 2013


Author: baranowb
Date: 2013-12-18 03:20:34 -0500 (Wed, 18 Dec 2013)
New Revision: 114607

Added:
   branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/
   branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/RolesAuthorizationTestCase.java
   branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/jmx-security-roles.xml
Modified:
   branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/AuthorizationTarget.java
   branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Operation.java
   branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Parser.java
   branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/RolesAuthorization.java
Log:
JBPAPP-10716 fix

Modified: branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/AuthorizationTarget.java
===================================================================
--- branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/AuthorizationTarget.java	2013-12-17 16:07:03 UTC (rev 114606)
+++ branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/AuthorizationTarget.java	2013-12-18 08:20:34 UTC (rev 114607)
@@ -22,7 +22,9 @@
 
 package org.jboss.jmx.connector.invoker.authorization.roles;
 
+import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import javax.management.ObjectName;
 
@@ -35,13 +37,13 @@
 public class AuthorizationTarget {
 
     private ObjectName objectName;
-    private Map<String, Operation> operations;
+    private List<Operation> operations;
 
     /**
      * @param objectName
      * @param operations2
      */
-    public AuthorizationTarget(ObjectName objectName, Map<String, Operation> operations) {
+    public AuthorizationTarget(ObjectName objectName, List<Operation> operations) {
         this.objectName = objectName;
         this.operations = operations;
     }
@@ -51,7 +53,14 @@
      * @return
      */
     public Operation matchOperation(String opname) {
-        final Operation target = operations.get(opname);
+        Operation target = null;
+        for(int index = 0; index < operations.size(); index++){
+            Operation o = this.operations.get(index);
+            if(Pattern.matches(o.getName(), opname)){
+                target = o;
+                break;
+            }
+        }
 
         if (target == null) {
             throw new SecurityException("No rules defined at: '" + objectName + "' for operation: " + opname);

Modified: branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Operation.java
===================================================================
--- branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Operation.java	2013-12-17 16:07:03 UTC (rev 114606)
+++ branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Operation.java	2013-12-18 08:20:34 UTC (rev 114607)
@@ -40,7 +40,7 @@
 
     /**
      * @param name
-     * @param roles 
+     * @param roles
      * @param objectName
      */
     public Operation(String name, List<Principal> roles, ObjectName objectName) {
@@ -59,6 +59,9 @@
         while (it.hasNext() && hasRole == false) {
             Principal p = it.next();
             hasRole = roles.isMember(p);
+            if (hasRole) {
+                break;
+            }
         }
         if (hasRole == false) {
             throw new SecurityException("Authorization failure,target='" + objectName + "', operation='" + name

Modified: branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Parser.java
===================================================================
--- branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Parser.java	2013-12-17 16:07:03 UTC (rev 114606)
+++ branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/Parser.java	2013-12-18 08:20:34 UTC (rev 114607)
@@ -104,7 +104,7 @@
         final Element nameElement = (Element) list.item(0);
         final String name = nameElement.getTextContent();
         final ObjectName objectName = new ObjectName(name);
-        Map<String, Operation> operations = new HashMap<String, Operation>();
+        List<Operation> operations = new ArrayList<Operation>();
 
         list = (NodeList) (XPATH.evaluate(OPERATIONS, authorizationTarget, XPathConstants.NODESET));
         if (list.getLength() == 0) {
@@ -116,7 +116,7 @@
         final int count = list.getLength();
         for (int index = 0; index < count; index++) {
             Operation op = parseOperation(list.item(index), objectName);
-            operations.put(op.getName(), op);
+            operations.add(op);
         }
 
         return new AuthorizationTarget(objectName, operations);

Modified: branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/RolesAuthorization.java
===================================================================
--- branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/RolesAuthorization.java	2013-12-17 16:07:03 UTC (rev 114606)
+++ branches/JBPAPP_5/server/src/main/org/jboss/jmx/connector/invoker/authorization/roles/RolesAuthorization.java	2013-12-18 08:20:34 UTC (rev 114607)
@@ -22,10 +22,12 @@
 
 package org.jboss.jmx.connector.invoker.authorization.roles;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.Principal;
 import java.security.acl.Group;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -36,6 +38,8 @@
 import javax.management.ObjectName;
 import javax.security.auth.Subject;
 
+import org.jboss.security.SimpleGroup;
+
 /**
  * Roles based authorization. This is advanced version of {@link org.jboss.jmx.connector.invoker.RolesAuthorization}. It
  * provides fine grained check against:
@@ -45,11 +49,35 @@
  * <li>user role</li> - determines( just like {@link org.jboss.jmx.connector.invoker.RolesAuthorization}) if current subject has
  * required role.
  * </ul>
- * This allows to define per role access level to certain MBeans and their methods. This implementation does not support wild
- * cards. It requires strict rules definition. If no rule is defined for target/method - it will deny access. Default
- * implementation requires configuration file(<b>jmx-security-roles.xml</b>) to be present in
- * <b>$JBOSS_HOME/server/${node}/conf</b>.<br>
+ * This allows to define per role access level to certain MBeans and their methods. Default implementation requires
+ * configuration file(<b>jmx-security-roles.xml</b>) to be present in <b>$JBOSS_HOME/server/${node}/conf</b>.<br>
  * Configuration file format looks as follows:<br>
+ * <br>
+ * <br>
+ * Note that 'wildcards' are supported. Valid MBean names:<br>
+ * <ul>
+ * <li>jboss:type=simple</li>
+ * <li>jboss:type=*</li>
+ * <li>jboss:*</li>
+ * </ul>
+ * <br>
+ * Operation names support regular expression, valid operation names:
+ * <ul>
+ * <li>invoke</li>
+ * <li>get*</li>
+ * <li>getData</li>
+ * </ul>
+ * <br>
+ * Be aware that this implementation considers rules as chains. This means that order of rule definition is important, in case
+ * of operation name and MBean name. <br>
+ * If authorization-target(3) MBean name match desired name, the authorization-target(4) is not processed, even though it may
+ * match MBean name:<br>
+ * desired name: jboss:data=simple,name=myname<br>
+ * authorization-target(3): jboss:data=simple,*<br>
+ * authorization-target(4): jboss:*<br>
+ * Operation name match works in similar way. <br>
+ * <br>
+ * Example configuration entry:
  * 
  * <pre>
  * &lt;authorization-rules&gt;
@@ -96,9 +124,9 @@
  */
 public class RolesAuthorization {
 
-    private static final String CONFIGURATION_FILE = "jmx-security-roles.xml";
+    protected static final String CONFIGURATION_FILE = "jmx-security-roles.xml";
 
-    private final Map<ObjectName, AuthorizationTarget> oname2Authorization = new HashMap<ObjectName, AuthorizationTarget>();
+    private List<AuthorizationTarget> authorizationTargets;
 
     /**
      * 
@@ -109,11 +137,11 @@
     }
 
     public void authorize(Principal caller, Subject subject, String objectname, String opname) {
-        Set groups = subject.getPrincipals(Group.class);
+        final Set<Group> groups = subject.getPrincipals(Group.class);
         Group roles = null;
-        Iterator iter = groups.iterator();
+        final Iterator<Group> iter = groups.iterator();
         while (iter.hasNext()) {
-            Group grp = (Group) iter.next();
+            Group grp = iter.next();
             if (grp.getName().equals("Roles")) {
                 roles = grp;
                 break;
@@ -123,10 +151,9 @@
             throw new SecurityException("Subject has no Roles, there is no way to assert access privilege!");
         }
 
-        AuthorizationTarget target = matchTraget(objectname);
+        final AuthorizationTarget target = matchTraget(objectname);
+        final Operation operation = target.matchOperation(opname);
 
-        Operation operation = target.matchOperation(opname);
-
         operation.assertPrivilege(roles);
 
     }
@@ -140,7 +167,14 @@
         } catch (NullPointerException e) {
             throw new SecurityException("Malformed taget name: '" + objectName + "'");
         }
-        AuthorizationTarget target = this.oname2Authorization.get(name);
+        AuthorizationTarget target = null;
+        for (int index = 0; index < this.authorizationTargets.size(); index++) {
+            AuthorizationTarget at = this.authorizationTargets.get(index);
+            if (at.getObjectName().apply(name)) {
+                target = at;
+                break;
+            }
+        }
 
         if (target == null) {
             throw new SecurityException("No rules defined for: '" + objectName + "'");
@@ -151,21 +185,25 @@
     protected void configure() throws Exception {
         InputStream is = null;
         try {
-            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIGURATION_FILE);
-            if (is == null) {
-                throw new IOException("Failed to read configuration file '" + CONFIGURATION_FILE
-                        + "' from server 'conf' directory!");
-            }
-            List<AuthorizationTarget> targets = Parser.parse(is);
-            for (AuthorizationTarget t : targets) {
-                this.oname2Authorization.put(t.getObjectName(), t);
-            }
+            is = this.getConfigurationStream();
+            this.authorizationTargets = Parser.parse(is);
         } finally {
-            if(is != null){
-                try{
+            if (is != null) {
+                try {
                     is.close();
-                }catch(Exception e){}
+                } catch (Exception e) {
+                }
             }
         }
     }
+
+    protected InputStream getConfigurationStream() throws Exception {
+        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIGURATION_FILE);
+        if (is == null) {
+            throw new IOException("Failed to read configuration file '" + CONFIGURATION_FILE
+                    + "' from server 'conf' directory!");
+        }
+        return is;
+
+    }
 }
\ No newline at end of file

Added: branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/RolesAuthorizationTestCase.java
===================================================================
--- branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/RolesAuthorizationTestCase.java	                        (rev 0)
+++ branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/RolesAuthorizationTestCase.java	2013-12-18 08:20:34 UTC (rev 114607)
@@ -0,0 +1,200 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.jmx.invoker.authorization;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.jboss.jmx.connector.invoker.authorization.roles.RolesAuthorization;
+import org.jboss.security.SimpleGroup;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.test.JBossTestCase;
+
+/**
+ * @author baranowb
+ * 
+ */
+public class RolesAuthorizationTestCase extends JBossTestCase {
+    private RolesAuthorization authorization;
+
+    /**
+     * @param name
+     */
+    public RolesAuthorizationTestCase(String name) {
+        super(name);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.authorization = new RolesAuthorization() {
+            @Override
+            protected InputStream getConfigurationStream() throws Exception {
+                return new FileInputStream(new File(".." + File.separator + "src" + File.separator + "main" + File.separator
+                        + "org" + File.separator + "jboss" + File.separator + "test" + File.separator + "jmx" + File.separator
+                        + "invoker" + File.separator + "authorization" + File.separator + super.CONFIGURATION_FILE));
+            }
+
+        };
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        this.authorization = null;
+        super.tearDown();
+    }
+
+    public void testAuthorization() throws Exception {
+        final String objectName = "jboss:service=JNDIView";
+        final String opName = "list";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("Tester"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        authorization.authorize(caller, subject, objectName, opName);
+    }
+
+    public void testWildarcMatch() throws Exception {
+        final String objectName = "jboss:service=NO_BOOM";
+        final String opName = "list";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("Tester"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+        } catch (SecurityException se) {
+            fail("Did not expect exception");
+        }
+    }
+    public void testWildarcMatch_2() throws Exception {
+        //this is ! to testNoRule_3
+        final String objectName = "jboss:type=NO_BOOM";
+        final String opName = "getSomeThingThatDoesNotExist";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("Tester"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+        } catch (SecurityException se) {
+            fail("Did not expect exception");
+        }
+    }
+    public void testNoRule() throws Exception {
+        final String objectName = "jboss:service=BOOM";
+        final String opName = "list";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("JBossAdmin"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+            fail("Expected SecurityException since there is no rule!");
+        } catch (SecurityException se) {
+            //
+        }
+    }
+
+    public void testNoRule_2() throws Exception {
+        final String objectName = "wicked_domain:service=BOOM";
+        final String opName = "list";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("JBossAdmin"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+            fail("Expected SecurityException since there is no rule!");
+        } catch (SecurityException se) {
+            //
+        }
+    }
+
+    public void testNoRule_3() throws Exception {
+        //test if first rule op def will match - it has only Tester role.
+        //second rule should never be triggered
+        final String objectName = "jboss:type=NO_BOOM";
+        final String opName = "getSomeThingThatDoesNotExist";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("JBossAdmin"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+            fail("Expected SecurityException since there is no rule!");
+        } catch (SecurityException se) {
+            //
+        }
+    }
+
+    public void testAuthorizationFailure() throws Exception {
+        final String objectName = "jboss:service=JNDIView";
+        final String opName = "list";
+        final Principal caller = new SimplePrincipal("test");
+        // yeah, this is stupid
+        final Group group = new SimpleGroup("Roles");
+        group.addMember(new SimplePrincipal("IWillBoom"));
+        final Set callers = new HashSet();
+        callers.add(caller);
+        callers.add(group);
+        final Subject subject = new Subject(false, callers, new HashSet(), new HashSet());
+        try {
+            authorization.authorize(caller, subject, objectName, opName);
+            fail("Expected SecurityException since there is no role!");
+        } catch (SecurityException se) {
+            //
+        }
+    }
+}

Added: branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/jmx-security-roles.xml
===================================================================
--- branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/jmx-security-roles.xml	                        (rev 0)
+++ branches/JBPAPP_5/testsuite/src/main/org/jboss/test/jmx/invoker/authorization/jmx-security-roles.xml	2013-12-18 08:20:34 UTC (rev 114607)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<authorization-rules>
+    <authorization-target>
+        <name>jboss:service=JNDIView</name>
+        <operations>
+            <operation>
+                <name>queryNames</name>
+                <roles>
+                    <role>JBossAdmin</role>
+                    <role>Tester</role> 
+                </roles>
+            </operation>
+            <operation>
+                <name>list</name>
+                <roles>
+                    <role>Tester</role>
+                    <role>JBossAdmin</role>
+                </roles>
+            </operation>
+        </operations>
+    </authorization-target>
+    <authorization-target>
+        <name>jboss:service=invoker,*</name>
+        <operations>
+            <operation>
+              <name>setRMIObjectPort</name>
+              <roles>
+                <role>JBossAdmin</role>
+              </roles>
+            </operation>
+            <operation>
+                <name>get.*</name>
+                <roles>
+                  <role>JBossAdmin</role>
+                  <role>Tester</role>
+                  <role>Babe</role>
+                </roles>
+            </operation>
+        </operations>
+    </authorization-target>
+    <authorization-target>
+        <name>jboss:*</name>
+        <operations>
+            <operation>
+              <!-- regex require . ... without it - dangling meta -->
+              <name>.*</name>
+              <roles>
+                <role>Tester</role>
+              </roles>
+            </operation>
+            <operation>
+                <name>get.*</name>
+                <roles>
+                  <role>JBossAdmin</role>
+                  <role>Babe</role>
+                </roles>
+            </operation>
+        </operations>
+    </authorization-target>
+</authorization-rules>
\ No newline at end of file



More information about the jboss-cvs-commits mailing list