向 ACL 添加限制会在 Jackrabbit Oak 中产生空的查询结果
Adding restrictions to ACLs yields empty results for queries in Jackrabbit Oak
使用 Jackrabbit Oak,我一直在尝试通过 SecurityProvider
和 SecurityConfiguration
来配置安全性。特别是,我一直在使用通常按预期工作的限制。但是,在处理 JCR-SQL2
查询时,比预期过滤掉的更多。
详情
可以使用下面的存储库进行复制。
/
node [nt:unstructured]
subnode [nt:unstructured]
在 node
上,我为 user
添加了一个具有权限 JCR_ALL
的访问控制条目以及对 rep:glob
-> ""
的限制,这样user
无法访问 node
的任何 children。
使用 session.getNode
时如预期工作:
session.getNode("/node")
returns 节点
session.getNode("/node/subnode")
由于限制而按预期抛出 PathNotFoundException
。
但是,当我执行以下 JCR-SQL2
查询时:
SELECT * FROM [nt:unstructured]
我没有返回结果。在这里我希望得到 /node
,因为在使用 session.getNode
.
时它是可用的
代码
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
}
如果要从上面的代码中删除 restrictions
,node
和 subnode
都会按预期出现在查询结果中。
MySecurityProvider
使用 ConfigurationParameters.EMPTY
和所有 SecurityConfiguration
的默认实现,除了我自己实现的 AuthenticationConfiguration
:
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);
}
};
}
}
我正在使用 Jackrabbit Oak 版本 1.10.0
这原来是 Jackrabbit Oak 中的一个错误 - Link to issue。
此问题已从 1.12.0 版开始得到解决
使用 Jackrabbit Oak,我一直在尝试通过 SecurityProvider
和 SecurityConfiguration
来配置安全性。特别是,我一直在使用通常按预期工作的限制。但是,在处理 JCR-SQL2
查询时,比预期过滤掉的更多。
详情
可以使用下面的存储库进行复制。
/
node [nt:unstructured]
subnode [nt:unstructured]
在 node
上,我为 user
添加了一个具有权限 JCR_ALL
的访问控制条目以及对 rep:glob
-> ""
的限制,这样user
无法访问 node
的任何 children。
使用 session.getNode
时如预期工作:
session.getNode("/node")
returns 节点session.getNode("/node/subnode")
由于限制而按预期抛出PathNotFoundException
。
但是,当我执行以下 JCR-SQL2
查询时:
SELECT * FROM [nt:unstructured]
我没有返回结果。在这里我希望得到 /node
,因为在使用 session.getNode
.
代码
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
}
如果要从上面的代码中删除 restrictions
,node
和 subnode
都会按预期出现在查询结果中。
MySecurityProvider
使用 ConfigurationParameters.EMPTY
和所有 SecurityConfiguration
的默认实现,除了我自己实现的 AuthenticationConfiguration
:
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);
}
};
}
}
我正在使用 Jackrabbit Oak 版本 1.10.0
这原来是 Jackrabbit Oak 中的一个错误 - Link to issue。
此问题已从 1.12.0 版开始得到解决