You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-issues@jackrabbit.apache.org by "angela (JIRA)" <ji...@apache.org> on 2019/01/21 16:04:00 UTC

[jira] [Commented] (OAK-7997) Adding restrictions to ACLs yields empty results for queries in Jackrabbit Oak

    [ https://issues.apache.org/jira/browse/OAK-7997?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16748049#comment-16748049 ] 

angela commented on OAK-7997:
-----------------------------

[~snj], i extracted a test case based on your description (directly operating on oak QueryEngine and oak API for simplicity) and i added some additional variants:

a) your case: single policy on /node with single entry + rep:glob restriction with empty value => unexpected result
b) policy on /node (allow) and another policy on /node/subnode (deny) => expected result (but obviously not practical in real life... just for the limited test-setup that's equivalent)

and while writing the summary i noticed a potential reason for the failure in a): with the ""-rep:glob we not only deny access to the child node but also to all properties of /node because the glob restriction is just a simple path-matching and doesn't differentiate between child properties and child nodes. to illustrate this (and because I suspect that the query looks at jcr:primaryType property) i added yet another test case 

c) same as a) but additionally granting property-read at /node/jcr:primaryType => expected result.

that's just for an initial illustration. i don't think that extra entry should be needed because in the JCR API implementation in Oak we added some extra logic to make sure a Node and its primary type information is accessible even if the {{jcr:primaryType}} property is not. So, with your setup {{Session.getNode("/node")}} succeeds and I think so does  {{Session.getNode("/node").getPrimaryNodeType()}}. but afaik {{Session.getNode("/node").getProperty("jcr:primaryType")}} and {{Session.getProperty("/node/jcr:primaryType")}} will fail because your test-session doesn't have the ability to read that property because of the ""-glob-restriction.

what i didn't find out until now is where exactly the query engine misses (skips) the result and if it's really because of the primary-type property...the only thing i found was {{org.apache.jackrabbit.oak.query.index.FilterImpl.isAccessible(String path)}} but somehow i never got there when debugging. that's what i will next (and reach out to the query team in case i get stuck)... more tomorrow.
 


> Adding restrictions to ACLs yields empty results for queries in Jackrabbit Oak
> ------------------------------------------------------------------------------
>
>                 Key: OAK-7997
>                 URL: https://issues.apache.org/jira/browse/OAK-7997
>             Project: Jackrabbit Oak
>          Issue Type: Bug
>          Components: query, security
>    Affects Versions: 1.10.0, 1.8.10
>            Reporter: Søren Jensen
>            Priority: Major
>         Attachments: OAK-7997.patch
>
>
> Using Jackrabbit Oak, I've been attempting to configure security through {{SecurityProvider}} and {{SecurityConfiguration's. In particular, I've been using the restrictions which generally works as expected. However, when dealing with JCR-SQL2}} queries, more gets filtered out than expected.
> *Details*
> It can be reproduced with the repository below.
> {code:java}
> / 
>   node      [nt:unstructured]
>     subnode [nt:unstructured] {code}
> On {{node}}, I add an access control entry with privilege {{JCR_ALL}} for "{{user"}} together with a restriction for {{rep:glob}} -> {{""}}, such that {{user}} do not have access to any children of {{node - in this case, only subnode}}.
> It works as expected when using {{session.getNode}}:
>  * {{session.getNode("/node")}} returns the node
>  * {{session.getNode("/node/subnode")}} throws {{PathNotFoundException}} as expected due to the restriction.
> However, when I execute the following {{JCR-SQL2}} query:
> {code:java}
> SELECT * FROM [nt:unstructured]{code}
> I get *no results back*. Here I would have expected to get {{/node}}, as it is otherwise available when using {{session.getNode}}. Removing the restriction yields the expected result of both _/node_ and _/node/subnode_.
> As discussed with [~anchela] on the _users_ mailing list, this may either be an actual bug, or it is a conscious decision - in which case it would be nice to have it documented for the security.
> *Code for reproducing:*
> The code for reproducing the error is shown below. The "_restrictions"_ map below seems to be the problem, as this is what results in both _/node_ and _/node/subnode_ being filtered out.
>  
> {code:java}
> public static void main(String[] args) throws Exception {
>     Repository repository = new Jcr().with(new MySecurityProvider()).createRepository();
>     Session session = repository.login(new UserIdCredentials(""));    // principal is "SystemPrincipal.INSTANCE"
>     // Create nodes
>     Node node = session.getRootNode().addNode("node", "nt:unstructured");
>     node.addNode("subnode", "nt:unstructured");
>     // Add access control entry + restriction
>     AccessControlManager acm = session.getAccessControlManager();
>     JackrabbitAccessControlList acl = (JackrabbitAccessControlList) acm
>         .getApplicablePolicies("/node").nextAccessControlPolicy();
>     Privilege[] privileges = new Privilege[]{acm.privilegeFromName(Privilege.JCR_ALL)};
>     Map<String, Value> restrictions = new HashMap<String, Value>() {{put("rep:glob", new StringValue(""));}};
>     acl.addEntry(new PrincipalImpl("user"), privileges, true, restrictions);
>     acm.setPolicy("/node", acl);
>     session.save();
>     // executes query
>     RowIterator rows = repository.login(new UserIdCredentials("user")).getWorkspace().getQueryManager()
>         .createQuery("SELECT * FROM [nt:unstructured]", Query.JCR_SQL2).execute().getRows();
>         System.out.println("Number of rows: " + rows.getSize());  //Prints 0
> }
> {code}
> *Code for security configuration:*
> The above code makes use of "MySecurityProvider". I do not suspect this to be the root cause, but please let me know if it can be helpful to have. The security provider has the configuration set to "ConfigurationParameters.EMPTY", and it uses all the default implementations present within the Jackrabbit Oak project. The only exception is the _AuthenticationConfiguration_ which uses a custom implementation using pre-authentication:
>  
> {code:java}
> class MyAuthenticationConfiguration extends AuthenticationConfigurationImpl {
>     public MyAuthenticationConfiguration(SecurityProvider securityProvider) {
>         super(securityProvider);
>     }
>     @NotNull
>     @Override
>     public LoginContextProvider getLoginContextProvider(ContentRepository contentRepository) {
>         return new LoginContextProvider() {
>             @NotNull
>             public LoginContext getLoginContext(Credentials credentials, String workspaceName) {
>                 String userId = ((UserIdCredentials) credentials).getUserId();
>                 Set<Principal> principalSets = new HashSet<>();
>                 if (userId.isEmpty()) {
>                     principalSets.add(SystemPrincipal.INSTANCE);
>                 } else {
>                     principalSets.add(new PrincipalImpl(userId));
>                 }
>                 Map<String, ? extends Principal> publicPrivileges = new HashMap<>();
>                 AuthInfoImpl authInfoImpl = new AuthInfoImpl(userId, publicPrivileges, principalSets);
>                 Subject subject = new Subject(true, principalSets, Collections.singleton(authInfoImpl), new HashSet<Principal>());
>                 return new PreAuthContext(subject);
>             }
>         };
>     }
> }
> {code}
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)