SharePoint Security and the Object Model – Part 1

This is the first part of a three part series. The other two parts are SharePoint Security and the Object Model – Part 2 and SharePoint Security and the Object Model – Part 3.

Users and Groups

In the spirit of my post the other day on claims and sign out, I decided to post a complete how-to that also goes along with a talk I do that you may have seen at a user group or SharePoint Saturday. This post is about creating groups and users. The last bit is about how to create a user from a claim.

Creating a Group

The SPGroupCollection class is a collection of SPGroup objects. An SPGroup represents a group in a SharePoint site. Properties of SPGroup include:

  • LoginName
  • Name
  • Description
  • ContainsCurrentUser
  • Owner
  • More…

Two key classes expose properties of type SPGroupCollection. The first is SPWeb. It exposes a Groups collection that contains all of the groups with permissions in the site. It also exposes a second property, SiteGroups, which contains all of the groups in the site collection.

Code to create a group


web.SiteGroups.Add("My Group", web.SiteAdministrators[0], null, "I made this with code!");
web.Update();

                
			

Get the newly created group as an SPGroup and add it to the AssociatedGroups collection so it displays on the quick launch on the Manage Permissions page.

SPGroup group = web.SiteGroups["My Group"];
web.AssociatedGroups.Add(group);
web.Update();

            

Creating a User

The SPUserCollection class is a collection of SPUser objects. SPWeb exposes three properties of type SPUserCollection.

  • AllUsers – Users with explicit membership or who have browsed to the site as authenticated users
  • SiteUsers – All users that belong to the site collection
  • Users – Users with explicit permissions in the site

The names of the first two, AllUsers and SiteUsers, is unfortunate and confusing. AllUsers applies to the site and SiteUsers applies to the entire site collection. Therefore, SiteUsers usually has more items than AllUsers!

The SPGroup.Users property is also of type SPUserCollection. It contains the users with explicit membership in the group.

SPWeb.EnsureUser

The previous section uses the term ‘explicit membership’ a couple of times. It is important to understand the difference between explicit and implicit membership in a site or a group.

Recall that an SPUser is a security principal recognized by the authentication provider and that it can be a user, group, role, or claim. If you add a user directly to a SharePoint group the user has explicit membership in the group. If you add a security principal like an AD group to a SharePoint group, the SPGroup.Users collection will contain a single SPUser instance that represents the AD group. Any users inside the AD group have implicit membership in the SharePoint group. The same is true of claims.

Implicit membership presents a challenge when writing code that deals with users and user information because it is possible and usually certain that there are users with access to a site that SharePoint does not know about via membership in a group. When a user logs in to a site for the first time SharePoint adds an SPUser to the site’s SiteUsers collection along with information about the user, but it is not uncommon to need information about a user who has implicit membership and has never logged in.

SPWeb’s EnsureUser method solves this problem. It ensures that a given name resolves by the authentication system (assuming this functionality is provided) and that it exists in the SiteUsers collection. Attempting to access an SPUser that does not exist throws an exception, and so you should always call EnsureUser whenever it is possible to have a login name and need to access user information for anyone other the current user. Examples include:

  • User name is in item metadata, e.g. Assigned To in a task
  • Code needs email address to send mail given user name
  • Co-worker or workflow assigns task to user who possibly has never accessed the site

The key takeaway is that the best way to get an instance of SPUser is to invoke EnsureUser.

Using EnsureUser with Claims

A claims name is an encoded value that consists of the claim type, issuer, and value, e.g. c:0ȉ.t|stsportalit|staff. The encoded value is what EnsureUser accepts to return an SPUser instance. The SPClaimProviderManager provides methods to encode and decode claims. To encode a claim, first create a new SPClaim. The SPClaim constructor accepts four arguments: claim type, value, value type, and original issuer. For example:

SPClaim claim = new
			

                
SPClaim(@"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
"Fred", ClaimValueTypes.String, "TrustedProvider:TrustedProviderName");

(Replace TrustedProviderName with the actual name of your provider!)

The next step is to decode the claim. First, get the local claim provider manager and then use it to get the encoded name.

string claimName = claimManager.EncodeClaim(claim);


 

Finally, pass the encoded claim to EnsureUser to get an SPUser instance.

SPUser user = SPContext.Current.Web.EnsureUser(claimName);


 

Adding an SPUser to an SPGroup

To add a user to a group, call the AddUser method of SPGroup.

SPContext.Current.Web.SiteGroups["My Group"].AddUser(user);

Author: Doug Ware