5 Replies Latest reply on Jul 1, 2015 3:57 AM by hchiorean

    Quick Setup to test visibility (Authentication/Authorization)

    journeycorner

      I am having a hard time to bootstrap ModeShape in a way it lets me test its Authentication and authorization - ModeShape 4 - Project Documentation Editor capabilities. All I want to do is hack around with roles set on a node basis to see how search relates to this in case of visibility and access, so I just need two sample roles to figure out if my hierachy is gonna work the way I want it to, e.g.:

       

      users admin and john doe - expected result: they can't see nodes/documents created by other users

       

      Is there an quick and dirty way to do this, without having to implement JAAS, use PicketBox, SpringSecurity or any other framework? You have some nice examples, but it's difficult to start from there - e.g. I tried to write some unit tests for modeshape-examples/modeshape-spring-security-example at master · ModeShape/modeshape-examples · GitHub since it seems to be the closet to my needs, but without any knowledge for Spring it's hard to do.

       

      Sorry if this is a duplicate question, but this website doesn't let me scroll search results: https://developer.jboss.org/search.jspa?q=jaas&place=%2Fplaces%2F249610&depth=ALL (testet in Firefox and Chrome).

        • 1. Re: Quick Setup to test visibility (Authentication/Authorization)
          hchiorean

          All I want to do is hack around with roles set on a node basis to see how search relates to this in case of visibility and access, so I just need two sample roles to figure out if my hierachy is gonna work the way I want it to, e.g.:

                 users admin and john doe - expected result: they can't see nodes/documents created by other users - See more at: https://developer.jboss.org/message/934662?et=watches.email.thread#934662

          By default, when searching, ModeShape will only check generic READ access on the nodes, based whatever authorization & authentication mechanism you have set up. There is no way around this, so if you're not using a container which already has JAAS enabled for example, you need to set a JAAS provider up - in our unit tests we use Pickebox for JAAS.

           

          If your use case is more complicated - i.e. both users have READ permissions but each should see a subset of nodes based on some context-dependent criteria, the only option is to implement your own authorization provider and configure ModeShape to use it. See Custom authentication providers - ModeShape 4 - Project Documentation Editor for more information. This means that you don't necessarily need to use one of the existing security providers (JAAS or Servlet) but then you need to implement the entire authentication & authorization logic in your own code.

          • 2. Re: Quick Setup to test visibility (Authentication/Authorization)
            journeycorner

            Thank you for the swift reply! My Implementation of the AuthenticationProvider works fine, however I don't know how to register my AuthorizationProvider (this seems to be the wrong place to register the authorizationProvider - modeshape tries to cast it to an authenticationprovider):

             

            "security" : {

               "anonymous" : {

               "roles" : ["readonly","readwrite","admin"],
               "useOnFailedLogin" : false
               },
               "providers" : [

              {

               "name" : "MAAS",
               "classname" : "org.modeshape.example.federation.maas.AuthenticationProviderImpl"
               },
               {

               "name" : "MAAS",
               "classname" : "org.modeshape.example.federation.maas.AuthorizationProviderImpl"
               }

              ]

            }

             

            Exception:

             

            Unable to initialize authentication provider "{ "name" : "MAAS2" , "classname" : "org.modeshape.example.federation.maas.AuthorizationProviderImpl" }" for repository "Federated Repository": org.modeshape.example.federation.maas.AuthorizationProviderImpl cannot be cast to org.modeshape.jcr.security.AuthenticationProvider

            java.lang.ClassCastException: org.modeshape.example.federation.maas.AuthorizationProviderImpl cannot be cast to org.modeshape.jcr.security.AuthenticationProvider

             

             

             

            Could you please comment my idea of a hierachy/permission system, I could not find any examples of it: I wan't to structure a document system like a unix file system, i.e. every user has a "home" directory at the root of all documents - I think this way search operations would be faster since only the child nodes of the user would be affected, is this correct? To share documents, I would put weak references in the home directory of the user I share it to. However, admin users need to see everything, so I am not sure how to put that into a data structure:

             

            /users/tom/docA

            /users/julia/docB

            /users/julia/weakLinkTo{/users/tom/docA}

            /users/admin/...?

             

            Is this a good idea? Are there any examples or other literature about jcr data structures concerning permission and read/search performance?

            • 3. Re: Quick Setup to test visibility (Authentication/Authorization)
              hchiorean

              Configuration wise, you should only implement & configure in JSON an AuthenticationProvider (and not an AuthorizationProvider). To hook up the AuthorizationProvider part, you need to use the security context. Have a look at modeshape/AuthenticationAndAuthorizationTest.java at master · ModeShape/modeshape · GitHub and modeshape/AuthenticationAndAuthorizationTest.java at master · ModeShape/modeshape · GitHub to better understand how this works. In essence, the authentication provider will set up a custom security context implementation which is also an AuthenticationProvider.

               

              Could you please comment my idea of a hierachy/permission system, I could not find any examples of it: I wan't to structure a document system like a unix file system, i.e. every user has a "home" directory at the root of all documents - I think this way search operations would be faster since only the child nodes of the user would be affected, is this correct?

               

              Search performance in ModeShape is more a function of the search criteria (plus index definitions in ModeShape 4 - i.e. limiting the amount of information that's indexed) and not so much a function of the underlying permissions scheme. In other words, the more specific (restrictive) a search criteria, the better since fewer nodes will need to be looked at. For example, searching only the children of a node under a given path is almost always faster than searching all the nodes under "/" (root) or performing multiple joins. Permission checking only comes into play after a set of nodes matching the search criteria have been found. From this perspective, this is identical to the case when you're retrieving a node by path: the exact same security checks will be performed in both cases. First ModeShape will retrieve the node from the repository and then it will ask the authorization provider(s) and/or access control managers (via ACLs) if that node can be read.

               

              To share documents, I would put weak references in the home directory of the user I share it to. However, admin users need to see everything, so I am not sure how to put that into a data structure:

              You can use weak node references but you can also use simple string properties (like node paths or identifiers) which may perform better depending on the case. You can also use more search criteria on String properties than on Reference properties.

              Is this a good idea? Are there any examples or other literature about jcr data structures concerning permission and read/search performance?

              I'm not aware of any blueprints anywhere, since JCR is a relatively vast spec that can be used and/or abused in any number of different ways, all of which are very much context dependent to a given problem. The best source of information is probably other people's usage patterns and experience.

               

              Regarding fine grained permissions in ModeShape you have 2 options:

              1. implement your custom security provider (as discussed above)
              2. use JCR ACLs - JCR 2.0: 16 Access Control Management (Content Repository for Java Technology API v2.0).

              Performance wise, both are expensive in general since it essentially means that *any* node related operations (reading/writing/searching/etc) will always go through some additional security layers. It's hard to say if one approach is better than the other, since it very much depends on the custom security provider implementation (i.e. a good/fast provider implementation may outperform ACLs). In the hierarchy structure that you mentioned both approaches would work. You can execute a search on an active session trying to find all the nodes which are under "/home/user" and then either 1. perform the permission logic in your own code or 2. rely on the previously set ACLs, in which case you don't need any additional code.

              • 4. Re: Quick Setup to test visibility (Authentication/Authorization)
                journeycorner

                I got the Authentication/Authorization to work with the implementation of your unit tests. Maybe someone can update Custom authentication providers - ModeShape 4 - Project Documentation Editor with the unit test code modeshape/AuthenticationAndAuthorizationTest.java at master · ModeShape/modeshape · GitHub, because this information is missing in the documentation.

                 

                However, I've still got a problem in setting up the AccessControlManager. I want to restrict every node of the home directory to be exclusively accessed by it's creator. That's why I create a new instance of Principial with the name of the logged in user. To restrict set the access, I used the code in Authentication and authorization - ModeShape 4 - Project Documentation Editor. My code throws an AccessDeniedException at "acm.getApplicablePolicies(path)", what am I missing?

                 

                 

                public static void addDocument(Session session) throws Exception {

                   Node userHome = session.getNode("/" + homeDir + "/" + session.getUserID());
                   Node newNode = userHome.addNode("document_" + session.getUserID() + "_id" + Math.random());

                   restrictAccess(session, new PrincipalImpl(session.getUserID()), new String[]{Privilege.JCR_ALL}, newNode.getPath());

                   session.save();
                }

                 

                private static void restrictAccess(Session session, Principal principal, String[] privileges, String path) throws Exception {

                  AccessControlManager acm = session.getAccessControlManager();

                   // Convert the privilege strings to Privilege instances ...
                   Privilege[] permissions = new Privilege[privileges.length];
                  for (int i = 0; i < privileges.length; i++) {

                  permissions[i] = acm.privilegeFromName(privileges[i]);
                   }

                 

                  AccessControlList acl = null;
                   AccessControlPolicyIterator it = acm.getApplicablePolicies(path);
                  if (it.hasNext()) {

                  acl = (AccessControlList)it.nextAccessControlPolicy();
                   } else {

                  acl = (AccessControlList)acm.getPolicies(path)[0];
                   }

                  acl.addAccessControlEntry(principal, permissions);
                }

                 

                javax.jcr.AccessDeniedException

                    at org.modeshape.jcr.AccessControlManagerImpl.getApplicablePolicies(AccessControlManagerImpl.java:165)

                    at org.modeshape.example.federation.ModeShapeHelper.restrictAccess(ModeShapeHelper.java:88)

                    at org.modeshape.example.federation.ModeShapeHelper.addDocument(ModeShapeHelper.java:73)

                    at org.modeshape.example.federation.ModeShapeExampleTest.shouldRunApplication(ModeShapeExampleTest.java:34)

                   ...

                • 5. Re: Quick Setup to test visibility (Authentication/Authorization)
                  hchiorean

                  That exception is thrown because this condition: modeshape/AccessControlManagerImpl.java at master · ModeShape/modeshape · GitHub fails (in turn this is checked here: https://github.com/ModeShape/modeshape/blob/master/modeshape-jcr/src/main/java/org/modeshape/jcr/security/acl/JcrAccessControlList.java#L132)

                   

                  Are you using both ACLs and your own custom provider at the same time ? If yes, you should debug the code and investigate why "hasPrivileges" is failing. In general however, you shouldn't need to use both at the same time. Is most cases you should use one or the other.