While access control management is a optional feature, a JCR implementation is required to support the basic permission checking. The basic requirements for the permission evalution are defines as follows
Permissions encompass the restrictions imposed by any access control restrictions that may be in effect upon the content of a repository, either implementation specific or JCR-defined (Access Control Management)., which consists of
The methods defined to check permissions:
Session#hasPermission(String absPath, String actions)
Session#checkPermission(String absPath, String actions)
JackrabbitSession.hasPermission(String absPath, @Nonnull String... actions)
(since Jackrabbit API 2.11.0 and Oak 1.4)The actions are expected to be a comma separated list of any of the following string constants:
Session.ACTION_READ
Session.ACTION_ADD_NODE
Session.ACTION_REMOVE
Session.ACTION_SET_PROPERTY
And defined by Jackrabbit API the following additional actions (since Jackrabbit API 2.11.0):
JackrabbitSession.ACTION_ADD_PROPERTY
JackrabbitSession.ACTION_MODIFY_PROPERTY
JackrabbitSession.ACTION_REMOVE_PROPERTY
JackrabbitSession.ACTION_REMOVE_NODE
JackrabbitSession.ACTION_NODE_TYPE_MANAGEMENT
JackrabbitSession.ACTION_VERSIONING
JackrabbitSession.ACTION_LOCKING
JackrabbitSession.ACTION_READ_ACCESS_CONTROL
JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL
JackrabbitSession.ACTION_USER_MANAGEMENT
Note: As of Oak 1.0 the these methods also handle the names of the permissions defined by Oak (see Permissions#getString(long permissions)
).
See also section Permissions vs Privileges for a comparison of these permission checks and testing privileges on the AccessControlManager
.
Important: absPath
refers to the node to be created
Node content = session.getNode("/content"); if (session.hasPermission("/content/newNode", Session.ACTION_ADD_NODE)) { content.addNode("newNode"); session.save(); }
Node content = jrSession.getNode("/content"); if (jrSession.hasPermission("/content", JackrabbitSession.ACTION_VERSIONING, JackrabbitSession.ACTION_LOCKING))) { content.checkin(); session.save(); }
Node content = session.getNode("/content"); if (session.hasPermission("/content", Permissions.getString(Permissions.VERSION_MANAGEMENT))) { content.checkin(); session.save(); }
As of Oak 1.0 Permission evaluation is intended to be completely separated from the access control management as defined by JCR and Jackrabbit API. While the evaluation and enforcing permissions is considered to be an internal feature of the Oak core module, the package org.apache.jackrabbit.oak.spi.security.authorization.permission
provides some extensions points that allow to plug custom extensions or implementations the evaluation (see API Extensions below).
Oak 1.0 defines the following Permissions:
Read operations:
READ_NODE
READ_PROPERTY
READ_ACCESS_CONTROL
Write operations:
ADD_NODE
REMOVE_NODE
MODIFY_CHILD_NODE_COLLECTION
ADD_PROPERTY
MODIFY_PROPERTY
REMOVE_PROPERTY
NODE_TYPE_MANAGEMENT
MODIFY_ACCESS_CONTROL
LOCK_MANAGEMENT
VERSION_MANAGEMENT
Since Oak 1.0:
USER_MANAGEMENT
: : execute user management related tasks such as e.g. creating or removing user/group, changing user password and editing group membership.INDEX_DEFINITION_MANAGEMENT
: create, modify and remove the oak:index node and it's subtree which is expected to contain the index definitions.Repository operations:
NODE_TYPE_DEFINITION_MANAGEMENT
NAMESPACE_MANAGEMENT
PRIVILEGE_MANAGEMENT
WORKSPACE_MANAGEMENT
Not used in Oak 1.0:
LIFECYCLE_MANAGEMENT
RETENTION_MANAGEMENT
READ
: aggregates READ_NODE
and READ_PROPERTY
REMOVE
: aggregates REMOVE_NODE
and REMOVE_PROPERTY
SET_PROPERTY
: aggregates ADD_PROPERTY
, MODIFY_PROPERTY
and REMOVE_PROPERTY
WRITE
: aggregates ADD_NODE
, REMOVE_NODE
and SET_PROPERTY
ALL
: aggregates all permissionsACTION_READ
:
Permissions.READ_ACCESS_CONTROL
Permissions.READ_NODE
Permissions.READ_PROPERTY
Permissions.READ
ACTION_ADD_NODE
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.ADD_NODE
ACTION_REMOVE
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.REMOVE_NODE
Permissions.REMOVE_PROPERTY
Permissions.REMOVE
ACTION_SET_PROPERTY
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.MODIFY_PROPERTY
Permissions.ADD_PROPERTY
ACTION_ADD_PROPERTY
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.ADD_PROPERTY
ACTION_MODIFY_PROPERTY
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.MODIFY_PROPERTY
ACTION_REMOVE_PROPERTY
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.REMOVE_PROPERTY
ACTION_REMOVE_NODE
:
Permissions.MODIFY_ACCESS_CONTROL
Permissions.REMOVE_NODE
ACTION_NODE_TYPE_MANAGEMENT
Permissions.NODE_TYPE_MANAGEMENT
ACTION_VERSIONING
Permissions.VERSION_MANAGEMENT
ACTION_LOCKING
Permissions.LOCK_MANAGEMENT
ACTION_READ_ACCESS_CONTROL
Permissions.READ_ACCESS_CONTROL
ACTION_MODIFY_ACCESS_CONTROL
Permissions.MODIFY_ACCESS_CONTROL
ACTION_USER_MANAGEMENT
Permissions.USER_MANAGEMENT
jcr:read
privilege will result in a backwards compatible read access for nodes and their properties, while specifying rep:readNodes
or rep:readProperties
privileges allows to grant or deny access to nodes and properties (see also Privilege Management for changes in the privilege definitions). Together with the restrictions this new behavior now allows to individually grant/deny access to properties that match a given name/path/nodetype (and as a possible extension even property value)./jcr:system/jcr:versionStore
is defined by the permissions present with the versionable node. In case the version information does no longer have a versionable node in this workspace it's original versionable path is used to evaluate the effective permissions that would apply to that item if the version was restored. This change is covered by OAK-444 and addresses concerns summarized in JCR-2963.READ_ACCESS_CONTROL
permission.SET_PROPERTY
permission has been split such to allow for more fined grained control on writing JCR properties. In particular Oak clearly distinguishes between creating a new property that didn't exist before, modifying or removing an existing property. This will allow to cover those cases where a given Subject
is only allowed to create content without having the ability to modify/delete it later on.Node#remove()
only requires sufficient permissions to remove the target node. See below for configuration parameters to obtain backwards compatible behavior.JackrabbitNode#rename
and a move with subsequent reordering.Writing protected items requires specific permissions and is not covered by regular JCR write permissions. This affects:
NODE_TYPE_MANAGEMENT
MODIFY_ACCESS_CONTROL
LOCK_MANAGEMENT
VERSION_MANAGEMENT
permission instead of the regular JCR write permissions. Similarly, the content in the version store can only be modified using the dedicated version management API.USER_MANAGEMENT
to be granted for the editing subject. This permission (including a corresponding privilege) has been introduced with Oak 1.0. See below for configuration parameters to obtain backwards compatible behavior.Permission evaluation is also applied when delivering observation events respecting the effective permission setup of the Session
that registered the EventListener
.
However, it is important to understand that events are only delivered once the modifications have been successfully persisted and permissions will be evaluated against the persisted state.
In other words: Changing the permission setup along with the modifications to be reported to the EventListener
will result in events being included or excluded according to the modified permissions. See OAK-4196 for an example.
Due to the separation of access control management from permission evaluation, Oak 1.0 comes with a dedicated API for permission discovery that is used both for the repository internal permission evaluation as well as for permission discovery at JCR level.
The package org.apache.jackrabbit.oak.spi.security.authorization.permission
defines the following interfaces and classes:
Tree
, exposed by PermissionProvider
.PermissionProvider
.As explained above permission evaluation is completely separated from the access control management and the associated ccontent. The evaluation itself is done by the configured PermissionProvider
.
Each JCR Session
(and Oak ContentSession
) gets it's own PermissionProvider
associated with the current repository revision the session is operating on. The evaluated permissions and caches are not shared between different sessions even if they represent the same subject.
see the corresponding documentation.
The behavior of the default permission implementation is described in sections Permissions: The Default Implementation and Permission Evaluation in Detail: The Default Implementation.
The configuration of the permission evaluation implementation is handled by the AuthorizationConfiguration, which is used for all authorization related matters. This class provides the following two permission related methods:
getPermissionProvider(Root, String, Set<Principal>)
: get a new PermissionProvider
instance.The supported configuration options of the default implementation are described in the corresponding section.