0

Works for administrator but not working for a normal user.

I even tried it with "SPSecurity.RunWithElevatedPrivileges(delegate() {});" after breaking RoleInheritance, and even tried "web.AllowUnsafeUpdates = true; ", it just don't wanna work.

If anyone knows a better way or just a fix ?, here's the code.

private void a()
{
    SPWeb web = SPControl.GetContextWeb(HttpContext.Current);

    foreach (SPWeb subweb in web.Webs)
    {
        using (subweb)
        {
            b(subweb);
        }
    }
}

public void b(SPWeb web)
{
    c(web.Url);

    int userCount = web.Users.Count - 1;

    for (int i = userCount; i >= 0; i--)
    {
        if (web.Users[i].IsDomainGroup)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate() {
                web.Users.Remove(i);
            });
        }
    }
}

public void c(string d)
{
    using (SPSite site = new SPSite(d))
    using (SPWeb web = site.OpenWeb())
    {
        web.AllowUnsafeUpdates = true;  
        web.BreakRoleInheritance(true);
        web.AllowUnsafeUpdates = false;  
    }
}

Or Simplified code is here (after Modifications) getting access denied now,

    private void RemoveAllGroupsFromSite()
    {
        SPWeb web = SPControl.GetContextWeb(HttpContext.Current);
        ParentWebUrl = web.ParentWeb.Url;
        SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                foreach (SPWeb subweb in web.Webs)
                {

                    using (subweb)
                    {
                        int userCount = subweb.Users.Count - 1;

                        subweb.AllowUnsafeUpdates = true;
                        subweb.BreakRoleInheritance(true);

                        for (int i = userCount; i >= 0; i--)
                        {
                            if (subweb.Users[i].IsDomainGroup)
                            {
                                //eweb.Site.WebApplication.FormDigestSettings.Enabled = false;
                                subweb.Users.Remove(i);
                                //eweb.Site.WebApplication.FormDigestSettings.Enabled = true;
                            }
                        }
                        subweb.AllowUnsafeUpdates = false;
                    }
                }
            });
    }

3 Answers 3

2

RunWithElevatedPrivileges only elavates privileges to SPSite's and SPWeb's if the SPSite is created inside the delegate and the SPWeb is retrieved from such a SPSite

So to get your code to work with RunWithElevatedPrivileges you need something like:

public void b(SPWeb web) 
{ 
  SPSecurity.RunWithElevatedPrivileges(delegate() {
    using (SPSite esite = new SPSite(web.Url))   
    using (SPWeb eweb = esite.OpenWeb())   
    {   

      int userCount = eweb.Users.Count - 1; 

      for (int i = userCount; i >= 0; i--) 
      { 
          if (eweb.Users[i].IsDomainGroup) 
          { 
            eweb.Users.Remove(i); 
          } 
      }
  }); 
} 

But in general you should try to limit use of RunWithElevatedPrivileges as much as possible and use Sites elevated using SystemToken instead see Daniel Larssons article Elevated Privilege with SPSite

6
  • Hi, Tried your code but getting another exception saying, "The security validation for this page is invalid.." I even tried "AllowUnsafeUpdates= true" but didn't helped. Apr 20, 2012 at 8:18
  • Where/how do you call the code? Apr 20, 2012 at 8:20
  • its a webpart, and on a Subweb Apr 20, 2012 at 8:24
  • it works when I put this statement in, but doesn't look good to use it my code tho "web.Site.WebApplication.FormDigestSettings.Enabled = false;" Apr 20, 2012 at 8:25
  • Where in the webpart? Just in browsing or when button is clicked? Where did you try to add the AllowUnsafeUpdates? Apr 20, 2012 at 8:36
1

You do not need to reset web.AllowUnsafeUpdate just before exiting a using() scope. That flag is reset when the web goes out of scope.

Incidentally, calling SPWeb.BreakRoleInheritance is also one of the very few cases where AllowUnsafeUpdate is also reset to true. So this entire block (in fact the entire call to c()) :

public void c(string d)
{
    using (SPSite site = new SPSite(d))
    using (SPWeb web = site.OpenWeb())
    {
        web.AllowUnsafeUpdates = true;  
        web.BreakRoleInheritance(true);
        web.AllowUnsafeUpdates = false;  
    }
}

Is exactly the same as just:

web.BreakRoleInheritance(true);

But without the huge overhead of reopening the entire SPSite and SPWeb.

Regardless of all this, you are most likely getting that access error because of improper use of RunWithElevatedPrivileges as pointed out by Per Jakbosen.

Finally, I don't know where you are using that code, but you should be conscious of the implicit security hole of fiddling with SPWeb.AllowUnsafeUpdates. If that code is executed by user input, consider refactoring so that you can use a POST request instead of GET, and use SPWeb.ValidateFormDigest() instead.

Excellent reading material:

What You Need To Know About AllowUnsafeUpdates (Part 1)

What You Need To Know About AllowUnsafeUpdates (Part 2)

BreakRoleInheritance and AllowUnsafeUpdates

0

this worked for me,

 private void a()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        web.AllowUnsafeUpdates = true;
                        web.BreakRoleInheritance(true);

                        foreach (SPWeb subweb in web.Webs)
                        {
                            using (subweb)
                            {
                                subweb.BreakRoleInheritance(true);
                                b(subweb);
                            }
                        }
                        web.AllowUnsafeUpdates = false;
                    }
                }
            });  
        }

        private static void b(SPWeb web)
        {
            int userCount = web.Users.Count - 1;
            List<SPUser> usersToDelete = new List<SPUser>();

            for (int i = userCount; i >= 0; i--)
            {
                if (web.Users[i].IsDomainGroup)
                    usersToDelete.Add(web.Users[i]);
            }

            foreach (SPUser user in usersToDelete)
            {
                web.AllowUnsafeUpdates = true;
                web.Users.Remove(user.LoginName);
            }
        }
1
  • As indicated by Per Jakobsen you should avoid using RunWithElevatedPrivileges. It needlessly elevates the network credentials of the logged on user. Use the SPSite overload and pass it the user token of the system account instead. RunWithElevatedPrivileges is a last resort to only be used in specific situations.
    – WebWires
    Apr 20, 2012 at 15:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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