Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I'm using the below code to activate the "SharePoint Server Publishing Infrastructure" feature for a site collection. My code runs fine when I'm logged in as a site collection administrator. The purpose is a less privileged user can also activate this feature, through my custom app page with a custom button with the following code behind.

SPSecurity.RunWithElevatedPrivileges(delegate()
        {           
                SPSite CurrentSite = SPContext.Current.Site;               
                CurrentSite.AllowUnsafeUpdates = true;
                CurrentSite.Features.Add(new Guid("{f6924d36-2fa8-4f0b-b16d-06b7250180fa}"));
                CurrentSite.AllowUnsafeUpdates = false;                         
        });

        }

For a less privileged user the pressing teh button results in the access denied page. And below data in the error logs:

Feature Activation: Activating Feature 'PublishingPrerequisites' (ID: 'a392da98-270b-4e85-9769-04c0fde267aa') at URL

Feature Activation: Failed to ensure feature dependencies for feature 'PublishingSite' (id: 'f6924d36-2fa8-4f0b-b16d-06b7250180fa'), exception thrown: System.Threading.ThreadAbortException: Thread was being aborted.
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at Microsoft.SharePoint.Utilities.SPUtility.Redirect(String url, SPRedirectFlags flags, HttpContext context, String queryString)
at Microsoft.SharePoint.Utilities.SPUtility.RedirectToAccessDeniedPage(HttpContext context)
at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(HttpContext context)
at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(Exception ex)
at Microsoft.SharePoint.SPSecurableObject.CheckPermissions(SPBasePermissions permissionMask)
at Microsoft.SharePoint.SPSecurity.ValidateSecurityOnOperation(SPOperationCode code, SPSecurableObject obj)
at Microsoft.SharePoint.SPFeature.AddRowToFeaturesTable(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce)
at Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce)
at Microsoft.SharePoint.SPFeatureCollection.AddInternal(SPFeatureDefinition featdef, Version version, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly)
at Microsoft.SharePoint.SPFeatureCollection.CheckSameScopeDependency(SPFeatureDefinition featdefDependant, SPFeatureDependency featdep, SPFeatureDefinition featdefDependency, Boolean fActivateHidden, Boolean fUpgrade, Boolean fForce, Boolean fMarkOnly)
at Microsoft.SharePoint.SPFeatureCollection.CheckFeatureDependency(SPFeatureDefinition featdefDependant, SPFeatureDependency featdep, Boolean fActivateHidden, Boolean fUpgrade, Boolean fForce, Boolean fMarkOnly, FailureReason& errType)
at Microsoft.SharePoint.SPFeatureCollection.CheckFeatureDependencies(SPFeatureDefinition featdef, Boolean fActivateHidden, Boolean fUpgrade, Boolean fForce, Boolean fThrowError, Boolean fMarkOnly, List`1& missingFeatures)
at Microsoft.SharePoint.SPFeatureCollection.CheckFeatureDependencies(SPFeatureDefinition featdef, Boolean fActivateHidden, Boolean fUpgrade, Boolean fForce, Boolean fMarkOnly)
at Microsoft.SharePoint.SPFeatureCollection.AddInternal(SPFeatureDefinition featdef, Version version, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly)

Updated (Working!) Code:

 private void SubmitButton_Click(object sender, EventArgs e){

        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite CurrentSite = new SPSite(SPContext.Current.Site.ID))
            {
                Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest();
                CurrentSite.Features.Add(new Guid("{f6924d36-2fa8-4f0b-b16d-06b7250180fa}"));
        });
    }
share|improve this question
    
May I know how can I get the GUID of a feature ? CurrentSite.Features.Add(new Guid("{f6924d36-2fa8-4f0b-b16d-06b7250180fa}")); Wim Hill, how did you got the GUID of that feature ? Thanks in advance. –  Zakir HC Feb 3 '12 at 13:18
add comment

3 Answers

up vote 10 down vote accepted

You should not use SPContext.Current.Site in the delegate method. Instead instantiate a new SPSite within the delegate. That's why you still get an access denied I would assume.

So, replace

SPSite CurrentSite = SPContext.Current.Site; 

With:

SPSite CurrentSite = new SPSite(SPContext.Current.Site.Id); 

And use a using statement around the CurrentSite like so:

using(SPSite CurrentSite = new SPSite(SPContext.Current.Site.Id))
{
       // your code
}
share|improve this answer
    
It didn't solve the issue but the error logging changed: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. (See Updated Code) –  Wim Hill Jan 25 '12 at 9:38
2  
That is because you stripped the AllowUnsafeUpdates away. Re-add this or try to use the SPUtility.ValidateFormDigest() method instead. –  Bernd Rickenberg Jan 25 '12 at 9:53
    
Removing the AllowUnsafeUpdates and adding Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest(); did the trick! Thanks Bernd! –  Wim Hill Jan 25 '12 at 10:18
    
You are still referencing SPContext inside the delegate. Grab the SPSite.ID before and use it in the ctor. –  Paul Schaeflein Jan 28 '12 at 17:37
add comment

Whenever you use 'RunWithElevatedPrviliges', we have to take the current context outside the SPSecurity.RunWithElevatedPrivileges block and then create a new instance of SPSite and SPWeb inside the that block which will run under application pool identity

 SPSecurity.RunWithElevatedPrivileges(delegate() 
    {
       using(SPSite site = new SPSite(SPContext.Current.Site.Id)
       {

            //code

       }   
    } 
share|improve this answer
    
It didn't solve the issue but the error logging changed: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. (See Updated Code) –  Wim Hill Jan 25 '12 at 9:33
    
see my updated response. –  Falak Mahmood Jan 25 '12 at 9:40
    
site.Update(); generates the following in VS: 'Microsoft.SharePoint.SPSite' does not contain a definition for 'Update' and no extension method 'Update'.... –  Wim Hill Jan 25 '12 at 9:56
    
As far as I know, site.Update(); is not required when using site.AllowUnsafeUpdates = true; because this property is not persisted: refer to this question sharepoint.stackexchange.com/questions/12675/… –  Kai Jan 25 '12 at 10:12
    
oh thanks for correction! –  Falak Mahmood Jan 25 '12 at 11:15
show 1 more comment

Be careful when using RunWithElevatedPrivileges, as it has alot of threading issues, and only works in specific cases where your current thread is impersonated (like in a web part, but not for example a feature receiver if its activated from PowerShell). Since your thread gets elevated to the application pool account, its permissions will vary on your security setup. This account might have permission to do stuff in the web application, but certainly should not have farm wide privileges!

I only use A more safe way to do elevation is to use yourSite.SystemAccount.UserToken and use it within

using (SPSite sites new SPSite(yourSite.ID, systemAccountToken))
{
    // do elevated stuff here
}

When that is said, there are PowerShell cmd-lets for what you are doing: open the SharePoint Management Console, and use commands like Get-SPFeature, Enable-SPFeature etc for this purpose.

More Features and Solution PowerShell cmdlets here
http://technet.microsoft.com/en-us/library/ee906539.aspx

More info here
http://solutionizing.net/2009/01/06/elegant-spsite-elevation/
and here http://stackoverflow.com/questions/1525953/sharepoint-2007-runwithelevatedprivileges-pitfalls-of-using-this

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.