MSDN Magazine - February 2008 - (Page 58) Figure 3 Impersonating a WSS User Identity SPWeb siteCollection = SPContext.Current.Site; SPWeb site = SPContext.Current.Web; // get SPUser object and acquire token SPUser targetUser = site.SiteUsers[@”LITWAREINC\BrianC”]; SPUserToken token = targetUser.UserToken; // create new SPSite and SPWeb object to impersonate user using (SPSite impersonatedSiteCollection = new SPSite(siteCollection.ID, token)) { using (SPWeb impersonatedSite = impersonatedSiteCollection.OpenWeb(site.ID)) { // WSS identity switched to impersonate BrianC // Windows identity does not change } } Why does this sample code fail after you have elevated the WSS user identity to SHAREPOINT\System? It has to do with when the SPSite object was created. The permissions in effect on an SPSite object and its child SPWeb objects do not depend on the current WSS user identity. Instead, the permissions depend on the WSS user identity at the time the SPSite object is created. Here, the SPSite object accessible through SPContext.Current was created earlier in the request, before your code had a chance to switch its WSS user identity. Thus, the technique you should use requires that you create a new SPSite object after you have called RunWithElevatedPrivileges and elevated WSS user identity to SHAREPOINT\System: SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite elevatedSiteCollection = new SPSite(this.Site.ID)) { using (SPWeb elevatedSite = elevatedSiteCollection.OpenWeb(this.Web.ID)) { // access elevatedSiteCollection and //elevatedSite as SHAREPOINT\System } } }); is different than a call to RunWithElevatedPrivileges because it does not change the current Windows identity. If, for example, a request is running under the Windows identity of LITWAREINC\ SP_WorkerProcess before you impersonate a WSS user, the code continues to run under the same Windows identity. WSS user impersonation does not change the current Windows identity over to the identity of the impersonated user. It is also important to point out that code must be running in a privileged state in order to impersonate another user. This isn’t something you have to worry about in an event handler or a custom workflow template since the code is running as SHAREPOINT\ System by default. However, code inside a Web Part or behind a custom application page might need to call RunWithElevatedPrivileges before it even has the ability to impersonate another WSS user identity. The real power in configuring WSS security involves the flexibility afforded by securable objects, such as sites, lists, and list items. Each securable object can contain an Access Control List (ACL), which is a binary data structure that WSS uses at run time to determine whether a security principal has been granted access. By default, the only securable object that has an ACL is the top-level site. Child objects (such as list, list items, and child site) all inherit the ACL of their parent unless they break the inheritance and thereby provide a unique ACL of their own. The WSS object model contains an interface named ISecurableObject that models a securable object within a WSS site collection (see Figure 4). The ISecurableObject interface, which is implemented by SPWeb objects, SPList objects, and SPItem objects, provides a basis for conducting access checks at run time as well as for configuring permissions. As you begin to configure permissions within a site collection, it’s important to understand that all of the sites, lists, and list items make up a single hierarchy of securable objects. By default, just the top-level site contains a unique ACL and defines permission-level assignments that dictate what permissions users have to access objects. All child objects inherit their permissions from the top-level site. However, you can be more granular about configuring access control by giving a securable object its own unique set of permis- Securable Objects This makes it possible to open a site collection and the sites within so that your code can access objects as SHAREPOINT\System. You might also find it necessary to impersonate a specific WSS user identity. This is common when writing the code for an event handler or a custom workflow template where the code is running as SHAREPOINT\System by default. For example, you might want to impersonate a specific WSS user identity before creating a new object so that WSS user is recognized as the owner of the new object. In order to impersonate a WSS user identity, you must first create an SPUserToken object. You can do this by accessing the UserToken property of an SPUser object. Once you have the SPUserToken object, you can use it to create a new SPSite object using an overloaded version of the SPSite class constructor. This technique is shown in Figure 3. There are a few important things I should point out about using WSS user impersonation. First, impersonating a WSS user Figure 4 The ISecurableObject Interface 58 msdnmagazine Office Space
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.