Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
An authority is a string representation of a user name, group name, or role name. Authorities can be assigned permissions to perform actions in the repository. This way, a certain user, or a certain group, or a certain role can be granted or denied permissions to do something
Some authorities are dynamic, such as the owner of a node and the owner of a lock held on a node.
These authorities are evaluated in the context of a node.
For some nodes you may be the 'owner' of that node. You will then have the permissions granted to the owner authority available to you.
Dynamic authorities are similar to an access policy. You can evaluate any condition knowing the node to be accessed and the current user and decide if the user should
have an authority in the given context. An access policy would be a dynamic permission assignment.
Groups can include both other groups and users so it is possible to construct hierarchies.
When any call is made to the repository through the public service API, the caller must first be authenticated.
This can be done by logging in using a username and password or using a ticket.
A ticket can be requested after logging in and can be used, under certain conditions, to revalidate a user.
Some applications and authentication mechanisms may support single sign on.
By default, the owner of a node is the person who created it. Ownership may be transferred to another user.
Only one user can own a node. However, other users may be able to take ownership of a node if they have suitable permission.
Permissions are identified by a string. A particular permission, for example 'ReadChildren', may be granted or denied to an authority; a user, group, administrator, owner, etc. The children of a node will inherit permissions from their parents if inheritance is set. So by default, the files in a folder will inherit their permissions from the folder. Permissions set on a node are additive with the inherited permissions from the parent nodes. If for example the parent is set to consumer, but the child is set for collaborator for the user, the user will have the sum of both permissions. The inheritance of permissions may be turned off for any node. A permission group is a convenient grouping of permissions such as 'Read' made up of 'ReadProperties' and 'ReadChildren'.
As the username is used as the key to find personal information, group membership and against which to assign permission, it is key to know if this is case sensitive or not.
The security framework as a whole may be case sensitive, or not.
Configuration of this key behaviour is set in repository.properties. It is quite unusual to have case sensitive user ids.
An ACL is a permission or permission group assigned to an authority for a particular node. An ACL can deny or allow. An 'allow' permission will be inherited by any children unless the permission is denied by an ACL on a child or inheritance of ACLs is disabled on a child. Allow takes precedence. If 'bob' is a member of the group 'rats' and 'bob' is allowed 'read' and 'rats' is denied 'read' then 'bob' will be allowed read. Any allow allows access, as opposed to a single deny denies all.
Global Permission - a permission or permission group assigned to an authority regardless of the node. A global permission takes precedence over node specific ACLS. If 'bob' were granted the global permission 'read' then 'bob' would have the 'read' permission for everything, regardless of any ACLs set on any nodes.
We think of role is an idea in the UI that refers to a set of permissions that can be applied to a folder. If you have role based permissions, this is not usually the same thing; it is really just another authority, like groups, with global permissions.
How are you using roles?
The diagram below shows some simple permissions that have applied to a basic directory structure. There are two users, Andy and Dave, to which permissions have been assigned. Permissions are also assigned to two special authorities: one that applies to all users and one that applies to the owner of a node. In this example, we are only interested in read, create and all permissions.
A summary of the permissions shown in the above diagram:
Authorization is enforced when methods are called on public services.
Access control is defined in meta-data and not in code.
The meta-data is used to 'inject' security in an aspect oriented way.
Security settings can therefore be changed without affecting the implementation code.
Security could be based on:
Security is enforced around public services. Web services, the UI, CIFS, WebDav, FTP etc all use public services and so include security enforcement. Public services are defined in public-services-context.xml.
Access control allows or prevents people from executing service methods on a particular object by checking if the current user, or any of the authorities granted to the current user, has a particular permission or permission group.
For example, on the NodeService bean, the readProperties method checks that the current user has read access to the properties of the node before invoking the method. On the SearchService, the results from queries are restricted to return only the nodes for which a user has read permission.
Authorization is enforced by defining proxies for each internal service implementation and adding. A method interceptor to enforce security is included in each proxy. When a method is called on a public service, the security interceptor is called before it returns execution to the internal implementation. At this stage, the interceptor can examine the function arguments to the method and check that the user has the appropriate rights for each in order to invoke the method.
For example, a method delete(NodeRef nodeRef) exists on the node service. The security interceptor can see the nodeRef argument before the underlying delete(...) method is called.
If configured correctly, the interceptor could check that the current user has 'Delete' permission for the node. If not, a security exception is raised. If permission allows the method goes ahead.
In a similar manner, after a method has executed the interceptor can examine the returned object and decided if it should return it the caller. For example, a search method could return a list of nodes. The security interceptor could filter this list for only those nodes that the current user can 'Read'.
It is possible you may want to configure a method so that it can only be called by an admin user, specific users, groups of users etc. This can also be enforced by the security method interceptor.
Access control for public services is defined in public-services-context.xml. The public services are the only Spring beans to have access restrictions.
Each service defines a method interceptor bean that enforces any security requirements for method calls. By convention, these are defined in public-services-security-context.xml, along with any other supporting beans. This file also defines the location from which the permission model is loaded.
Here is the v1.0 public services security context as an example PublicServicesSecurityContext
In public-services-security-context.xml the beans required to support Acegi based security around method invocation are defined.
This configures two alfresco specific beans: a voter that can veto method execution based on the permissions granted to the current user for specific arguments to the method, and an after invocation provider to apply security to objects returned by methods. Method access defined in the normal acegi way with a few additions.
In the following: ? represents an authority (user name or group), # a method argument index and * a string representation of a permission.
Pre-conditions take one of the following forms:
If more than one ACL_NODE.#.* or ACL_PARENT.#.* entry is present then all the permissions must be available for the method to execute.
Post-conditions take the forms:
The post-conditions will create access denied exceptions for return types like NodeRef's, StoreRef's, ChildAssociationRef's. For collections and arrays members will be filtered based on the access conditions.
Some examples and explanations taken from the method security interceptor for the NodeService public service bean.
Refer to the NodeService interface for the method documentation and methos parameters etc.
org.alfresco.service.cmr.repository.NodeService.getStores=AFTER_ACL_NODE.sys:base.Read
If the returned object is a collection or array then filter its members to contain only those that can be read by the current user.
If it is a single reference to a node of some form, throw an AccessDeniedException.
org.alfresco.service.cmr.repository.NodeService.createStore=ACL_METHOD.ROLE_ADMINISTRATOR
Allow access to users who are members of the administrator group.
(This does not use an acegi ROLE_... as we do not bind groups and roles to the Acegi authentication object.
org.alfresco.service.cmr.repository.NodeService.exists=ACL_NODE.0.sys:base.Read
Only allow for users who have read permission for the node specified by the first parameter of the method.
org.alfresco.service.cmr.repository.NodeService.createNode=ACL_NODE.0.sys:base.CreateChildren
Only allow for users who have create children permission for the node specified by the first parameter of the method.
org.alfresco.service.cmr.repository.NodeService.moveNode=ACL_NODE.0.sys:base.WriteProperties,ACL_PARENT.0.sys:base.DeleteChildren,ACL_NODE.1.sys:base.CreateChildren
Only users who can write the properties of the moving node, remove the node from its parent, and ann children to the destination node can perform a move node.
org.alfresco.service.cmr.repository.NodeService.setChildAssociationIndex=ACL_PARENT.0.sys:base.WriteProperties
Setting the index of an association requires the write properties permissions
org.alfresco.service.cmr.repository.NodeService.getType=ACL_NODE.0.sys:base.ReadProperties
Getting the type of a node required read permission for properties.
org.alfresco.service.cmr.repository.NodeService.addAspect=ACL_NODE.0.sys:base.Write
Adding an aspect to a node requires the write permission set.
org.alfresco.service.cmr.repository.NodeService.removeAspect=ACL_NODE.0.sys:base.Write
Remoing an aspect from a node requires the write permission set.
org.alfresco.service.cmr.repository.NodeService.hasAspect=ACL_NODE.0.sys:base.ReadProperties
Querying if a node has an aspect requires the read properties permission on the node.
org.alfresco.service.cmr.repository.NodeService.getAspects=ACL_NODE.0.sys:base.ReadProperties
Getting a list of all aspects for a node requires the read properties permission on the node.
org.alfresco.service.cmr.repository.NodeService.deleteNode=ACL_NODE.0.sys:base.Delete
Deleting a node requires the delete permission. Testing for delete on the children is not possible for performance reasons.
The node service should retest this for each node that it tries to delete.
org.alfresco.service.cmr.repository.NodeService.addChild=ACL_NODE.0.sys:base.CreateChildren,ACL_NODE.1.sys:base.ReadProperties
Adding children to a node requires the create children property on the parent and read properties on the node (this ensures that you can see the child node)
org.alfresco.service.cmr.repository.NodeService.removeChild=ACL_NODE.1.sys:base.Delete
To remove a child node you need delete permission for the child (this includes the test to see if it is deletable from the parent.)
org.alfresco.service.cmr.repository.NodeService.getProperties=ACL_NODE.0.sys:base.ReadProperties
Accessing the properties of a node requires the permission to read properties.
org.alfresco.service.cmr.repository.NodeService.getProperty=ACL_NODE.0.sys:base.ReadProperties
Accessing a particular property on a node requires the permission to read properties.
org.alfresco.service.cmr.repository.NodeService.setProperties=ACL_NODE.0.sys:base.WriteProperties
Setting all properties on a node required the permission to write properties.
org.alfresco.service.cmr.repository.NodeService.setProperty=ACL_NODE.0.sys:base.WriteProperties
Setting a specific property on a node required the permission to write properties.
org.alfresco.service.cmr.repository.NodeService.getParentAssocs=ACL_NODE.0.sys:base.ReadProperties,AFTER_ACL_PARENT.sys:base.Read
Getting the parent associations on a node requires read access to the node. The method only reports the parents that are visible.
There may be mutiple parents some of which are not visible. You must have access via the primary parent to read a node.
org.alfresco.service.cmr.repository.NodeService.getChildAssocs=ACL_NODE.0.sys:base.ReadChildren,AFTER_ACL_NODE.sys:base.Read
Reading child associations requires read access to the node and filters for only the children that are visible.
org.alfresco.service.cmr.repository.NodeService.getPrimaryParent=ACL_NODE.0.sys:base.ReadProperties,AFTER_ACL_PARENT.sys:base.Read
Accessing the primary parent requires that the node and its primary parent are accessible. In future, we may allow access along a link and not just the primary parent, in which case it is possible that the primary parent is not visible.
org.alfresco.service.cmr.repository.NodeService.createAssociation=ROLE_AUTHENTICATED
org.alfresco.service.cmr.repository.NodeService.removeAssociation=ROLE_AUTHENTICATED
org.alfresco.service.cmr.repository.NodeService.getTargetAssocs=ROLE_AUTHENTICATED
org.alfresco.service.cmr.repository.NodeService.getSourceAssocs=ROLE_AUTHENTICATED
Currently, there are no retrictions on the creation of associations between nodes.
org.alfresco.service.cmr.repository.NodeService.getPath=ACL_NODE.0.sys:base.ReadProperties
Getting the primary path to a node requires read access to the node.
org.alfresco.service.cmr.repository.NodeService.getPaths=ACL_NODE.0.sys:base.ReadProperties
Getting all the paths to a node requires read access to the node.