Difference between revisions of "Home Library: Security and user management"
(→How Resource-based ACLs are stored) |
(→Permissions through Workspace) |
||
(125 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
|} | |} | ||
− | + | Starting from gCube 3.0, Home Library delivers Access Control Management, with the following: | |
+ | *'''User & group management''': To create, update and delete users and groups in the JCR. | ||
+ | *'''Assigning access control policies''': Setting the privileges that a user has in relation to a node using access control policies. | ||
+ | *'''Privilege discovery''': Determining the privileges that a user has in relation to a node. | ||
+ | |||
+ | |||
+ | JCR 2.0 delivers Access Control Management. The JCR API package is '''javax.jcr.security'''. | ||
+ | It covers the authorization part, ie. what a certain user is allowed to do with the repository. | ||
+ | |||
+ | Jackrabbit provides an additional API for security and user management located in '''org.apache.jackrabbit.api.security.user'''. | ||
− | |||
− | |||
==Managing users and groups== | ==Managing users and groups== | ||
+ | |||
+ | Using the Home Library that contains JCR APIs, you can create, update and delete users and groups. Users and Groups are stored in the repository as JCR nodes. | ||
− | + | The HL administator can: | |
− | *List users | + | *'''List users''': to list existing users; |
− | *Create user | + | *'''Create user''': to create a new user by username and password; |
− | + | *'''List groups''': to list existing groups; | |
− | *List groups | + | *'''Get group''': to retrieve the properties of a single group; |
− | *Get group | + | *'''Create group''': to create a new group; |
− | *Create group | + | *'''Update group''': the name of the group can NOT be updated, only the membership is updateable; |
− | *Update group | + | *'''Delete authorizable (user or group)''': to delete an existing user or group. |
− | *Delete group | + | |
− | |||
− | |||
− | + | ===UserManager Interface=== | |
− | + | Home Library delivers an UserManager interface to create, update and delete users and group in the JCR. | |
− | + | ||
− | = | + | <source lang="java"> |
− | + | import org.gcube.common.homelibrary.home.workspace.usermanager.UserManager; | |
− | + | import org.gcube.common.homelibrary.home.workspace.usermanager.GCubeGroup; | |
− | + | ..... | |
+ | public class TestUserManager { | ||
+ | private void test() { | ||
+ | UserManager gm = HomeLibrary.getHomeManagerFactory().getUserManager(); | ||
+ | .... | ||
+ | } | ||
+ | ... | ||
+ | </source> | ||
+ | ===List users=== | ||
+ | The method | ||
− | === | + | <source lang="java"> |
− | A privilege represents the ability to perform a particular set of operations on a node. | + | public List<String> getUsers() throws InternalErrorException; |
− | + | </source> | |
+ | |||
+ | lists existing users. | ||
+ | |||
+ | ===Create user=== | ||
+ | |||
+ | The method | ||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean createUser(String name, String vre) throws InternalErrorException; | ||
+ | </source> | ||
+ | |||
+ | creates a new user, where name is the ''name'' of the new user and ''vre'' is the vre which the user belongs to. The method returns true if it has been created. | ||
+ | |||
+ | ===List groups=== | ||
+ | |||
+ | To list existing groups: | ||
+ | |||
+ | <source lang="java"> | ||
+ | public List<GCubeGroup> getGroups() throws InternalErrorException; | ||
+ | </source> | ||
+ | |||
+ | ===Get group=== | ||
+ | |||
+ | The method | ||
+ | |||
+ | <source lang="java"> | ||
+ | public GCubeGroup getGroup(String groupname) throws InternalErrorException; | ||
+ | </source> | ||
+ | |||
+ | retrieves a single user. ''groupname'' would be replace with the name of the group. | ||
+ | |||
+ | ===Create group=== | ||
+ | |||
+ | The method | ||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean createGroup(String groupName) throws InternalErrorException; | ||
+ | </source> | ||
+ | |||
+ | creates a new group. Groupname would be replace with the name of the group. | ||
+ | |||
+ | ===Update group=== | ||
+ | |||
+ | To update an existing group, the following methods are available through the '''GCubeGroup''' interface: | ||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean addMember(String user) throws InternalErrorException; | ||
+ | </source> | ||
+ | adds a specified ''user'' to the group. | ||
+ | It returns true if the member was successfully added, false if the user was already a member. | ||
+ | |||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean addMembers(List<String> users) throws InternalErrorException; | ||
+ | </source> | ||
+ | adds a list of users to the group. | ||
+ | It returns true if the member was successfully added, false if the user was already a member. | ||
+ | |||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean removeMember(String user) throws InternalErrorException; | ||
+ | </source> | ||
+ | removes the specified ''user'' from the group. | ||
+ | It returns true if the user was removed, or false if the user was not a member. | ||
+ | |||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean removeMembers(List<String> users) throws InternalErrorException; | ||
+ | </source> | ||
+ | removes a list of users from the group. | ||
+ | It returns true if the list of users was removed. | ||
+ | |||
+ | ===Delete group=== | ||
+ | |||
+ | <source lang="java"> | ||
+ | /** | ||
+ | * Delete a group | ||
+ | * @param name of a group or user | ||
+ | * @return true if it has been deleted | ||
+ | * @throws InternalErrorException | ||
+ | */ | ||
+ | public boolean deleteAuthorizable(String name) throws InternalErrorException; | ||
+ | </source> | ||
+ | |||
+ | ===Associate a User To a Group=== | ||
+ | The method | ||
+ | |||
+ | <source lang="java"> | ||
+ | public boolean associateUserToGroup(String scope, String username) | ||
+ | </source> | ||
+ | |||
+ | returns true if the user has been successfully associated to the VRE Group. The param "scope" is the complete VRE scope (e.g. "/gcube/devsec/devVRE") and "username" is the user that you want to add to the VRE Group. | ||
+ | |||
+ | ===Remove a User from a Group=== | ||
+ | |||
+ | The method | ||
+ | <source lang="java"> | ||
+ | public boolean removeUserFromGroup(String scope, String username) | ||
+ | </source> | ||
+ | |||
+ | returns true if the user has been successfully removed from the VRE Group. Also in this case, the param "scope" is the complete VRE scope (e.g. "/gcube/devsec/devVRE") and username is the user that you want to remove from the VRE Group. | ||
+ | |||
+ | ==Managing permessions== | ||
+ | |||
+ | Permissions, called "privileges", are defined by the JCR 2.0 specification. | ||
+ | |||
+ | A privilege represents the ability to perform a particular set of operations on a node. This is basically the set of read, create, modify and delete operations that can be done on nodes and properties via the JCR API. A repository can also define custom privileges. | ||
===Permissions / Privileges=== | ===Permissions / Privileges=== | ||
− | |||
Basic privileges: | Basic privileges: | ||
Line 58: | Line 178: | ||
**jcr:write and the advanced permssions. | **jcr:write and the advanced permssions. | ||
− | |||
− | + | Custom privileges: | |
− | * | + | *'''hl:noOwnershipLimit''': The privilege to handle nodes of everyone. |
+ | *'''hl:writeAll''': An aggregate privilege that contains: | ||
+ | **jcr:write, | ||
+ | **hl:noOwnershipLimit | ||
+ | *'''hl:removeSharedRoot''': The privilege to remove a shared root. | ||
+ | |||
+ | |||
+ | |||
+ | Code to create the custom privileges: | ||
+ | |||
+ | <source lang="java"> | ||
+ | |||
+ | PrivilegeManager am = HomeLibrary.getHomeManagerFactory().getPrivilegeManager(); | ||
+ | am.createCostumePrivilege("hl:noOwnershipLimit", new String[] {}); | ||
+ | am.createCostumePrivilege("hl:writeAll", new String[] {"jcr:write", "hl:noOwnershipLimit"}); | ||
+ | am.createCostumePrivilege("hl:removeSharedRoot", new String[] {}); | ||
+ | |||
+ | </source> | ||
===ACL Model=== | ===ACL Model=== | ||
Line 71: | Line 207: | ||
====How Resource-based ACLs are stored==== | ====How Resource-based ACLs are stored==== | ||
− | Resource-based ACLs are stored per resource/node in a special child node rep:policy. This one will have a list of '''rep:GrantACE''' child nodes (usually named allow, allow0,...) for grant access control entries | + | Resource-based ACLs are stored per resource/node in a special child node '''rep:policy'''. |
− | Each ACE node has a '''rep:principalName''' STRING property pointing to the user or group this ACE belongs to | + | This one will have a list of: |
+ | *'''rep:GrantACE''' child nodes (usually named allow, allow0,...) for grant access control entries | ||
+ | *'''rep:DenyACE''' child nodes (usually named deny, deny0,...) for deny access control entries. | ||
+ | |||
+ | Each ACE node has | ||
+ | *a '''rep:principalName''' STRING property pointing to the user or group this ACE belongs to | ||
+ | *a '''rep:privileges''' NAME multi-value property, containing all the privileges of this ACE. | ||
===Repository Configuration=== | ===Repository Configuration=== | ||
− | To use the Resource-based ACL mechanism, a different AccessControlProvider has been configured. This is set in the <Workspace/> element of the repository.xml. | + | To use the Resource-based ACL mechanism, a different AccessControlProvider has been configured. This is set in the '''<Workspace/>''' element of the '''repository.xml'''. |
<source lang="xml"> | <source lang="xml"> | ||
Line 83: | Line 225: | ||
</source> | </source> | ||
− | ===Permissions | + | In addition, the LoginModule has been modified to use the DefaultLoginModule that authenticates users with Jackrabbit repository: |
+ | |||
+ | <source lang="xml"> | ||
+ | <LoginModule class="org.apache.jackrabbit.core.security.authentication.DefaultLoginModule"> | ||
+ | <param name="adminId" value="xxx" /> | ||
+ | <param name="adminPassword" value="xxx" /> | ||
+ | </LoginModule> | ||
+ | </source> | ||
+ | |||
+ | ===AccessManager Interface=== | ||
+ | Home Library delivers an AccessManager interface to manipulate users permissions in the JCR. | ||
+ | |||
+ | <source lang="java"> | ||
+ | |||
+ | import org.gcube.common.homelibrary.home.workspace.accessmanager.AccessManager; | ||
+ | |||
+ | ..... | ||
+ | public class TestAccessManager { | ||
+ | private void test() { | ||
+ | AccessManager am = HomeLibrary.getHomeManagerFactory().getAccessManager(); | ||
+ | .... | ||
+ | } | ||
+ | ... | ||
+ | </source> | ||
+ | |||
+ | ====Get Permissions==== | ||
+ | |||
+ | To get the permissions which are effective for a particular node: | ||
+ | |||
+ | <source lang="java"> | ||
+ | Map<String, List<String>> permissionsMap = am.getEACL(absPath); | ||
+ | </source> | ||
+ | |||
+ | ====Set Read-Only Permission==== | ||
+ | To allow users to only read files: | ||
+ | |||
+ | <source lang="java"> | ||
+ | List<String> users = new ArrayList<String>(); | ||
+ | users.add("test.user1"); | ||
+ | users.add("test.user2"); | ||
+ | am.setReadOnlyACL(users, absPath); | ||
+ | </source> | ||
+ | |||
+ | ====Set Write-Owner Permission==== | ||
+ | To allow users to create files, but to edit and delete just own files. | ||
+ | |||
+ | <source lang="java"> | ||
+ | List<String> users = new ArrayList<String>(); | ||
+ | users.add("test.user1"); | ||
+ | users.add("test.user2"); | ||
+ | am.setWriteOwnerACL(users, absPath); | ||
+ | </source> | ||
+ | |||
+ | ====Set Write-All Permission==== | ||
+ | To allow users to create, edit and delete files of everyone in the share. | ||
+ | |||
+ | <source lang="java"> | ||
+ | List<String> users = new ArrayList<String>(); | ||
+ | users.add("test.user1"); | ||
+ | users.add("test.user2"); | ||
+ | am.setWriteAllACL(users, absPath); | ||
+ | </source> | ||
+ | |||
+ | ====Set Administrator Permission==== | ||
+ | To grant all privileges: | ||
+ | |||
+ | <source lang="java"> | ||
+ | List<String> users = new ArrayList<String>(); | ||
+ | users.add("test.user1"); | ||
+ | users.add("test.user2"); | ||
+ | am.setAdminACL(users, absPath); | ||
+ | </source> | ||
+ | |||
+ | ===Permissions through Workspace=== | ||
+ | The methods to set and retrieve permissions from the Workspace are available through the interface org.gcube.common.homelibrary.home.workspace.WorkspaceSharedFolder. | ||
+ | |||
+ | ====ACLType==== | ||
+ | The repository supports 4 standard privileges identified by the string constants of org.gcube.common.homelibrary.home.workspace.accessmanager.ACLType: | ||
+ | |||
+ | *'''READ_ONLY''': this permission grants the ability to read the files in the shared folder. | ||
+ | *'''WRITE_OWNER''': this permission grants the ability to create and modify their own files. This includes the creating, deleting, moving and renaming, just for the own files. | ||
+ | *'''WRITE_ALL''': this permission grants the ability to modify the content of a shared folder. This includes creating files, deleting files, moving files and renaming files. It will not be allowed to delete the shared folder root. | ||
+ | *'''ADMINISTRATOR''': this permission grants the ability to perform every actions on the shared folder. An administrator can also delete the shared folder root. | ||
+ | |||
+ | ====Setting Permissions==== | ||
+ | |||
+ | The method | ||
+ | <source lang="java"> | ||
+ | void setACL(List<String> users, ACLType privilege) | ||
+ | </source> | ||
+ | binds a ACL privilege to the shared folder for a list of users. | ||
+ | |||
+ | ====Retrieving Permissions==== | ||
+ | |||
+ | The method | ||
+ | <source lang="java"> | ||
+ | Map<String, ACLType> getACL() | ||
+ | </source> | ||
+ | returns a Map of privileges that have been set to the Shared Folder for each group. | ||
+ | |||
+ | ==Permissions checking== | ||
+ | |||
+ | Home Library provides a Class (PrivilegesInfo) to know what actions the current user is provisioned to do on an existing node. | ||
+ | The PrivilegesInfo provides methods for checking the following actions: | ||
+ | |||
+ | *'''addChildren''': Checks if the current user may add new nodes; | ||
+ | *'''canModifyProperties''': Checks if the current user may update the properties of the specified node; | ||
+ | *'''canDelete''': Checks if the current user may remove a specified node. | ||
+ | |||
+ | Every time a user does an action in the Workspace (move, create, rename, delete or update files), the | ||
+ | HL will check if such user has the privilege to perform the action. | ||
− | + | InsufficientPrivilegesException is thrown when the user is denied access to the data. This is because the authorization rules associated with the owner of the session do not allow the requested access. | |
− | + |
Latest revision as of 15:23, 24 July 2017
Starting from gCube 3.0, Home Library delivers Access Control Management, with the following:
- User & group management: To create, update and delete users and groups in the JCR.
- Assigning access control policies: Setting the privileges that a user has in relation to a node using access control policies.
- Privilege discovery: Determining the privileges that a user has in relation to a node.
JCR 2.0 delivers Access Control Management. The JCR API package is javax.jcr.security.
It covers the authorization part, ie. what a certain user is allowed to do with the repository.
Jackrabbit provides an additional API for security and user management located in org.apache.jackrabbit.api.security.user.
Managing users and groups
Using the Home Library that contains JCR APIs, you can create, update and delete users and groups. Users and Groups are stored in the repository as JCR nodes.
The HL administator can:
- List users: to list existing users;
- Create user: to create a new user by username and password;
- List groups: to list existing groups;
- Get group: to retrieve the properties of a single group;
- Create group: to create a new group;
- Update group: the name of the group can NOT be updated, only the membership is updateable;
- Delete authorizable (user or group): to delete an existing user or group.
UserManager Interface
Home Library delivers an UserManager interface to create, update and delete users and group in the JCR.
import org.gcube.common.homelibrary.home.workspace.usermanager.UserManager; import org.gcube.common.homelibrary.home.workspace.usermanager.GCubeGroup; ..... public class TestUserManager { private void test() { UserManager gm = HomeLibrary.getHomeManagerFactory().getUserManager(); .... } ...
List users
The method
public List<String> getUsers() throws InternalErrorException;
lists existing users.
Create user
The method
public boolean createUser(String name, String vre) throws InternalErrorException;
creates a new user, where name is the name of the new user and vre is the vre which the user belongs to. The method returns true if it has been created.
List groups
To list existing groups:
public List<GCubeGroup> getGroups() throws InternalErrorException;
Get group
The method
public GCubeGroup getGroup(String groupname) throws InternalErrorException;
retrieves a single user. groupname would be replace with the name of the group.
Create group
The method
public boolean createGroup(String groupName) throws InternalErrorException;
creates a new group. Groupname would be replace with the name of the group.
Update group
To update an existing group, the following methods are available through the GCubeGroup interface:
public boolean addMember(String user) throws InternalErrorException;
adds a specified user to the group. It returns true if the member was successfully added, false if the user was already a member.
public boolean addMembers(List<String> users) throws InternalErrorException;
adds a list of users to the group. It returns true if the member was successfully added, false if the user was already a member.
public boolean removeMember(String user) throws InternalErrorException;
removes the specified user from the group. It returns true if the user was removed, or false if the user was not a member.
public boolean removeMembers(List<String> users) throws InternalErrorException;
removes a list of users from the group. It returns true if the list of users was removed.
Delete group
/** * Delete a group * @param name of a group or user * @return true if it has been deleted * @throws InternalErrorException */ public boolean deleteAuthorizable(String name) throws InternalErrorException;
Associate a User To a Group
The method
public boolean associateUserToGroup(String scope, String username)
returns true if the user has been successfully associated to the VRE Group. The param "scope" is the complete VRE scope (e.g. "/gcube/devsec/devVRE") and "username" is the user that you want to add to the VRE Group.
Remove a User from a Group
The method
public boolean removeUserFromGroup(String scope, String username)
returns true if the user has been successfully removed from the VRE Group. Also in this case, the param "scope" is the complete VRE scope (e.g. "/gcube/devsec/devVRE") and username is the user that you want to remove from the VRE Group.
Managing permessions
Permissions, called "privileges", are defined by the JCR 2.0 specification.
A privilege represents the ability to perform a particular set of operations on a node. This is basically the set of read, create, modify and delete operations that can be done on nodes and properties via the JCR API. A repository can also define custom privileges.
Permissions / Privileges
Basic privileges:
- jcr:read: The privilege to retrieve a node and get its properties and their values.
- jcr:modifyProperties: The privilege to create, remove and modify the values of the properties of a node.
- jcr:addChildNode: The privilege to create child nodes of a node.
- jcr:removeNode: The privilege to remove a node.
- jcr:removeChildNodes: The privilege to remove child nodes of a node.
- jcr:write: An aggregate privilege that contains:
- jcr:read,
- jcr:modifyProperties,
- jcr:addChildNodes,
- jcr:removeNode,
- jcr:removeChildNodes
- jcr:all: An aggregate privilege that contains all available permissions, including:
- jcr:read,
- jcr:write and the advanced permssions.
Custom privileges:
- hl:noOwnershipLimit: The privilege to handle nodes of everyone.
- hl:writeAll: An aggregate privilege that contains:
- jcr:write,
- hl:noOwnershipLimit
- hl:removeSharedRoot: The privilege to remove a shared root.
Code to create the custom privileges:
PrivilegeManager am = HomeLibrary.getHomeManagerFactory().getPrivilegeManager(); am.createCostumePrivilege("hl:noOwnershipLimit", new String[] {}); am.createCostumePrivilege("hl:writeAll", new String[] {"jcr:write", "hl:noOwnershipLimit"}); am.createCostumePrivilege("hl:removeSharedRoot", new String[] {});
ACL Model
Resource-based ACLs
Resource-based ACLs are the default access control mechanism in Jackrabbit 2.x. That means that a resource = node is associated with a list of allow/deny entries for certain principals (users or groups), which naturally maps to store them along the JCR node. A core concept of resource-based ACLs is that they inherit the ACLs from the parent node, thus for each node, all the ACLs of its ancestor come into play as well.
How Resource-based ACLs are stored
Resource-based ACLs are stored per resource/node in a special child node rep:policy. This one will have a list of:
- rep:GrantACE child nodes (usually named allow, allow0,...) for grant access control entries
- rep:DenyACE child nodes (usually named deny, deny0,...) for deny access control entries.
Each ACE node has
- a rep:principalName STRING property pointing to the user or group this ACE belongs to
- a rep:privileges NAME multi-value property, containing all the privileges of this ACE.
Repository Configuration
To use the Resource-based ACL mechanism, a different AccessControlProvider has been configured. This is set in the <Workspace/> element of the repository.xml.
<WorkspaceSecurity> <AccessControlProvider class="org.apache.jackrabbit.core.security.authorization.acl.ACLProvider" /> </WorkspaceSecurity>
In addition, the LoginModule has been modified to use the DefaultLoginModule that authenticates users with Jackrabbit repository:
<LoginModule class="org.apache.jackrabbit.core.security.authentication.DefaultLoginModule"> <param name="adminId" value="xxx" /> <param name="adminPassword" value="xxx" /> </LoginModule>
AccessManager Interface
Home Library delivers an AccessManager interface to manipulate users permissions in the JCR.
import org.gcube.common.homelibrary.home.workspace.accessmanager.AccessManager; ..... public class TestAccessManager { private void test() { AccessManager am = HomeLibrary.getHomeManagerFactory().getAccessManager(); .... } ...
Get Permissions
To get the permissions which are effective for a particular node:
Map<String, List<String>> permissionsMap = am.getEACL(absPath);
Set Read-Only Permission
To allow users to only read files:
List<String> users = new ArrayList<String>(); users.add("test.user1"); users.add("test.user2"); am.setReadOnlyACL(users, absPath);
Set Write-Owner Permission
To allow users to create files, but to edit and delete just own files.
List<String> users = new ArrayList<String>(); users.add("test.user1"); users.add("test.user2"); am.setWriteOwnerACL(users, absPath);
Set Write-All Permission
To allow users to create, edit and delete files of everyone in the share.
List<String> users = new ArrayList<String>(); users.add("test.user1"); users.add("test.user2"); am.setWriteAllACL(users, absPath);
Set Administrator Permission
To grant all privileges:
List<String> users = new ArrayList<String>(); users.add("test.user1"); users.add("test.user2"); am.setAdminACL(users, absPath);
Permissions through Workspace
The methods to set and retrieve permissions from the Workspace are available through the interface org.gcube.common.homelibrary.home.workspace.WorkspaceSharedFolder.
ACLType
The repository supports 4 standard privileges identified by the string constants of org.gcube.common.homelibrary.home.workspace.accessmanager.ACLType:
- READ_ONLY: this permission grants the ability to read the files in the shared folder.
- WRITE_OWNER: this permission grants the ability to create and modify their own files. This includes the creating, deleting, moving and renaming, just for the own files.
- WRITE_ALL: this permission grants the ability to modify the content of a shared folder. This includes creating files, deleting files, moving files and renaming files. It will not be allowed to delete the shared folder root.
- ADMINISTRATOR: this permission grants the ability to perform every actions on the shared folder. An administrator can also delete the shared folder root.
Setting Permissions
The method
void setACL(List<String> users, ACLType privilege)
binds a ACL privilege to the shared folder for a list of users.
Retrieving Permissions
The method
Map<String, ACLType> getACL()
returns a Map of privileges that have been set to the Shared Folder for each group.
Permissions checking
Home Library provides a Class (PrivilegesInfo) to know what actions the current user is provisioned to do on an existing node. The PrivilegesInfo provides methods for checking the following actions:
- addChildren: Checks if the current user may add new nodes;
- canModifyProperties: Checks if the current user may update the properties of the specified node;
- canDelete: Checks if the current user may remove a specified node.
Every time a user does an action in the Workspace (move, create, rename, delete or update files), the HL will check if such user has the privilege to perform the action.
InsufficientPrivilegesException is thrown when the user is denied access to the data. This is because the authorization rules associated with the owner of the session do not allow the requested access.