Search Results for

    Show / Hide Table of Contents

    Configuring site security

    In SharePoint the definition of what a user or group can do on a securable object (Web, List, ListItem) is defined as a role (a.k.a. permission level). For example the role "Full Control" has many permissions like "Manage Lists", "View Items" and more. The default owners group of a site has the "Full Control" role granting all users and groups part of the owners group the related permissions like "Manage Lists", "View Items" and more. Roles are always managed at the root web level, meaning there's only one set of roles defined per site collection.

    By default securable objects inherit permissions: the permissions set on the site are inherited by each list and the are again inherited by each list item. If a user is then added to the site's contributors group he immediately has the "Full Control" role on all of the content in the site. However, sometimes it's need to provide other permissions for a sub site, for a list or for a list item which is implemented by breaking the permission inheritance for the securable object followed by setting the correct permissions on the securable object.

    In the remainder of this article you'll see a lot of context use: in this case this is a PnPContext which was obtained via the PnPContextFactory as explained in the overview article and show below:

    using (var context = await pnpContextFactory.CreateAsync("SiteToWorkWith"))
    {
        // See next chapter on how to use the PnPContext for working with lists
    }
    

    Configuring roles

    Listing the existing roles

    To query the roles defined on the IWeb instance load the RoleDefinitions property on the root web of the site collection.

    var roleDefinitions = (await context.Web.GetAsync(p => p.RoleDefinitions)).RoleDefinitions;
    foreach(role in roleDefinitions)
    {
        // do something with the role
        // Typical roles are "Full Control", "Edit", "Contribute", ...
    }
    

    Understanding if a role has a permission

    To verify if a role has a given permission level you can use

    // Context is a root web context
    var roleDefinition = await context.Web.RoleDefinitions.FirstOrDefaultAsync(d => d.Name == "Full Control");
    if (roleDefinition.BasePermissions.Has(PermissionKind.ViewPages))
    {
        // The "Full Control" role has the "View Pages" permission
    }
    

    Adding a custom role

    If the default roles and their associated permissions do not fit your needs you can create a new role.

    Note

    It's not recommended to change the out of the box provided roles.

    // Load the roles, context is a root web context
    var roleDefinitions = (await context.Web.GetAsync(p => p.RoleDefinitions)).RoleDefinitions;
    // Add a custom role
    var customRole = await roleDefinitions.AddAsync("My custom role", 
                                                    RoleType.None, 
                                                    new PermissionKind[] 
                                                    { 
                                                        PermissionKind.ViewPages, 
                                                        PermissionKind.ViewListItems 
                                                    }, 
                                                    "Limited viewing only");
    

    Updating a role

    A role can also be updated, simply call one of the Update methods after having changed the role. The change the permissions a role has use the Clear and Set methods on the BasePermissions property:

    var customRole = await context.Web.RoleDefinitions.FirstOrDefaultAsync(d => d.Name == "My custom role");
    
    customRole.BasePermissions.Clear(PermissionKind.ViewPages);
    customRole.BasePermissions.Set(PermissionKind.AddListItems);
    customRole.Description = "Custom role";
    // Send update to server
    await customRole.UpdateAsync();
    

    Deleting a role

    Deleting a role can be done via the Delete methods:

    var customRole = await context.Web.RoleDefinitions.FirstOrDefaultAsync(d => d.Name == "My custom role");
    // Delete the role
    await customRole.DeleteAsync();
    

    Assigning roles

    To actually grant a permission a role needs to be assigned to a user or group. By default the groups and user and their assigned roles are maintained at the root web level and you can directly grant roles via the user and group models, which is explained in the respective Groups and Users pages. It's however also possible to break permission inheritance and have different permissions at sub web, list or list item level. In PnP Core SDK the three objects that can be secured (IWeb, IList and IListItem) all implement the ISecurableObject interface providing the needed properties and methods to configure security.

    Note

    The below chapters use an IList as sample but they apply to either IWeb, IList and IListItem.

    Breaking permission inheritance

    By default permissions are inherited, so each securable object inherits from it's securable object parent. If you want to configure different permissions for let's say an IList then you need to first break permission inheritance using one of the BreakRoleInheritance methods. Using the first method parameter copyRoleAssignments can opt to copy over the current permissions so that you can edit them later on. If set to false then no permissions are copied over. The second parameter clearSubscopes determines what will happen with the existing custom permissions: imagine the scenario where that a list in a sub has custom permissions set and then the custom permissions are defined on the web which is the list's ISecurableObject parent. When clearSubscopes is set to true then existing custom permissions on securable child objects are dropped in favor of the current one, if set to false the existing custom permissions are left as is.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    // Break permission inheritance
    await myList.BreakRoleInheritanceAsync(false, true);
    

    Restoring permission inheritance

    If a securable object again needs to inherit the permissions from it's securable parent object then use one of the ResetRoleInheritance methods.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    // Reset permission inheritance
    await myList.ResetRoleInheritanceAsync();
    

    Listing the current roles a user or group has on a securable object

    To get a list of the currently assigned roles for a securable object use the GetRoleDefinitions methods. Simply pass in the id of principal (= user or group) you want to get the roles for.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    // Load the role assignments on this list, also load the role definitions
    await myList.LoadAsync(w => w.RoleAssignments.QueryProperties(p => p.RoleDefinitions));
    
    foreach (var roleAssignment in myList.RoleAssignments.AsRequested())
    {
        // do something with the role assignment
    }
    

    Checking if custom permissions are defined

    Checking if a securable object has custom role assignments is done via the HasUniqueRoleAssignments.

    Note

    When loading data you can apply a filter (via the where() LINQ operator) and you can filter on HasUniqueRoleAssignments == true when querying webs and lists, however this is not possible when querying list items.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    // Load the role assignments on this list, also load the role definitions
    await myList.LoadAsync(w => w.HasUniqueRoleAssignments);
    
    if (myList.HasUniqueRoleAssignments)
    {
        // List has custom permissions set, let's reset them
        await myList.ResetRoleInheritanceAsync();
    }
    

    Assigning roles to a user or group

    Once you've broken permissions inheritance you will often assign roles for one or more users and groups to the securable object. To do so there are approaches: doing a bulk role assignment via the AddRoleDefinitions methods or assigning one role via the AddRoleDefinition methods. Both are shown in below example.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    
    // Get current user
    var currentUser = await context.Web.GetCurrentUserAsync();
    
    // Approach A: adding single role to the current user
    var roleDefinitions = (await context.Web.GetAsync(p => p.RoleDefinitions)).RoleDefinitions;
    var editRole = roleDefinitions.AsRequested().FirstOrDefault(p => p.Name == "Edit");
    
    await myList.AddRoleDefinitionAsync(currentUser.Id, editRole);
    
    // Approach B: adding multiple roles at once
    await myList.AddRoleDefinitionsAsync(currentUser.Id, new string[] { "Full Control", "Edit" });
    

    Removing roles from a user or group

    Just like adding roles there's also options for removing roles from a user or group for a securable object: doing a bulk role removal via the RemoveRoleDefinitions methods or removing one role via the RemoveRoleDefinition methods. Both are shown in below example.

    var myList = await context.Web.Lists.GetByTitleAsync("mylist");
    
    // Get current user
    var currentUser = await context.Web.GetCurrentUserAsync();
    
    // Approach A: remove single role to the current user
    var roleDefinitions = (await context.Web.GetAsync(p => p.RoleDefinitions)).RoleDefinitions;
    var editRole = roleDefinitions.AsRequested().FirstOrDefault(p => p.Name == "Edit");
    
    await myList.RemoveRoleDefinitionAsync(currentUser.Id, editRole);
    
    // Approach B: Removing multiple roles at once
    await myList.RemoveRoleDefinitionsAsync(currentUser.Id, new string[] { "Full Control", "Edit" });
    
    Back to top PnP Core SDK
    Generated by DocFX with Material UI
    spacer