One of my little pet peeves is an application that has hard-coded look ups for specific Active Directory groups or specific SharePoint groups in order to activate certain pieces of functionality. While this works and makes sense to most programmers it lacks a certain amount of elegance and of course locks you into the groups and their roles that have been defined during the initial design and development of the application or website.
I think it is much more cleaner to instead create roles or permission levels and grant them to groups in order to activate the functionality you want. The advantage of architecting your solution this way is that it allows the end user admins to create their own customized set of groups after the application has been rolled out without having to deploy additional code. The way I usually set up a SharePoint group is as a container for individuals and AD groups, and then specify the customized permissions for each group.
For instance, if I have a basic support function I want made accessible, and I have 3 different levels of support SharePoint groups, I could design it this way:
What this does for me is I now have 3 different support groups, but instead of having to check for if the user is a member of one of 3 SharePoint groups, I just have to check if the collection of AllRolesForCurrentUser has my custom defined role in order to activate the functionality. And if later I want to add another SharePoint group called “Support Administrator” that only has access to the Administrator Support functions, I can do this from within the SharePoint UI after the application has been deployed.
In order to create custom permission levels, there are couple of ways of doing this, either through the GUI or from custom code:
From http://technet.microsoft.com/en-us/library/cc263239(v=office.14).aspx
Create a permission level
If there is no permission level similar to the one you need, you can create one.
To create a permission level
Verify that you have one of the following administrative credentials:
You are a member of the Administrators group for the site collection.
You are a member of the Owners group for the site.
You have the Manage Permissions permission.
On the Site Settings page, under Users and Permissions, click Site permissions.
In the Manage section of the ribbon, click Permission Levels.
On the toolbar, click Add a Permission Level.
On the Add a Permission Level page, in the Name field, type a name for the new permission level.
In the Description field, type a description of the new permission level.
In the list of permissions, select the check boxes to add permissions to the permission level.
Click Create.
Or through Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SharePoint; namespace CustomPermissionLevel { class Program { static void Main(string[] args) { using (SPSite site = new SPSite("http://sharepoint/")) { using (SPWeb web = site.RootWeb) { SPRoleDefinition role = new SPRoleDefinition(); role.Name = "Custom Permission Level"; role.Description = "Description: Custom Permission level"; role.BasePermissions = SPBasePermissions.AddAndCustomizePages | SPBasePermissions.ApplyStyleSheets; web.RoleDefinitions.Add(role); } } } } }
Or through PowerShell:
$site=Get-SPSite "http://sharepoint/" $web=$site.RootWeb; $customPermissionLevel=New-Object Microsoft.SharePoint.SPRoleDefinition $customPermissionLevel.Name="Custom Permission Level" $customPermissionLevel.Description="Description: Custom Permission Level Test" $customPermissionLevel.BasePermissions="EmptyMask” $web.RoleDefinitions.Add($customPermissionLevel); $web.Dispose() $site.Dispose()
Note: If you want to add additional SharePoint specific permissions to the Role/Permission here is a list of the other values you can assign to BasePermissions:
ViewListItems, AddListItems, EditListItems, DeleteListItems, ApproveItems, OpenItems, ViewVersions, DeleteVersions, CancelCheckout, ManagePersonalViews, ManageLists, ViewFormPages, Open, ViewPages, AddAndCustomizePages, ApplyThemeAndBorder, ApplyStyleSheets, ViewUsageData, CreateSSCSite, ManageSubwebs, CreateGroups, ManagePermissions, BrowseDirectories, BrowseUserInfo, AddDelPrivateWebParts, UpdatePersonalWebParts, ManageWeb, UseClientIntegration, UseRemoteAPIs, ManageAlerts, CreateAlerts, EditMyUserInfo, EnumeratePermissions, FullMask
Once your Role has been defined, you can see it in the Permission Levels of your Site Security section:
And it can be used to grant this permission level to specific SharePoint Groups or even individuals.
Now that we’ve got our custom role and assign it to a user or group so it will show up in the user’s AllRolesForCurrentUser, how do we use it?
In our WebPart where we want to check the functionality, just use code similar to this:
SPWeb web = SPContext.Current.Web; //**************************************** // Validate the page request to avoid // any malicious posts if (Request.HttpMethod == "POST") SPUtility.ValidateFormDigest(); //**************************************** // Get a reference the roles that are // bound to the current user and the role // definition to which we need to verify // the user against SPRoleDefinitionBindingCollection usersRoles = web.AllRolesForCurrentUser; SPRoleDefinitionCollection roleDefinitions = web.RoleDefinitions; SPRoleDefinition roleDefinition = roleDefinitions["Custom Permission Level"]; // Check if the user is in the role. If not // redirect the user to the access denied page if (usersRoles.Contains(roleDefinition)) { //******************************* //Check if post back to run //code that initiates the page if (IsPostBack != true) { // Enable your stuff here } } else { // User does not have permissions to this functionality }
And now we have a SharePoint application that is permission level aware instead of group level aware. We can create as many groups or individuals as we want and assign them these permission levels without having to recode the application to check for these groups, and the business units can mix and match permissions however they want as the group and business needs change during the lifecycle of the project.