none
Elevated privileges problem RRS feed

  • Question

  • Hi,

    I have read around the issue (Ishai Sagi, Maurice Prather etc). I'm just not sure whether this is actually my problem....

     

    I have a web part that is attempting to display the memberships of any user in the profile database. The display should work for any logged in user.

     

    My code uses SPSecurity.RunWithElevatedPrivileges delegate to get the userprofile object and from thence the membershipmanager object, then GetItems.

     

    When this code runs, not all memberships are retrieved. In fact, in my production environment, the only way to get any items listed is to log in as Sharepoint\system.

     

    I found the override IgnoreUserPrivacy (http://msdn2.microsoft.com/en-us/library/ms570916.aspx) which is sadly undocumented thinking that this would give me the results I want. However, when I add this to my code, the page then fails with a 403. Debugging shows that "you must have manage user profiles administrator rights to use administrator mode". With the RunElevatedPriviliges method, I had assumed that the code executes as the app pool account. I therefore gave the app pool account "manage user profiles" permissions in SSP. However, this made no difference. I cannot seem to find out what account the code is executing as.

     

    So, I can make the web part work but not retrieve any info from the profile database, or, I can invoke what appear to be special rights, but then the wbe part fails (its a 403 as per numerous other postings).

     

    Does this come under Maurice's issue about the HTTPContext security context? Does nayone have any insight into the IgnoreUserPrivacy parameter? Does anyone have anything like this working (or suggest an alternate method)?

     

    TIA

    Mark

    Friday, August 31, 2007 9:34 AM

Answers

  • Is your app pool account the same as the app pool account for the ssp web application? You are basically doing a function which normally would be done from the ssp web application. Therefore, you may want to either change the app pool account to use the app pool account being used in the ssp or check to make sure the current app pool account has dbo rights to the ssp content database, read/write rights to all content databases associated  with the ssp, read rights to the configuration database and read rights for the central administration content database.

     

    Tuesday, September 4, 2007 1:54 PM
  • One thing I have noticed in a couple of these posts is the SPContext is used or SPSite/SPWeb objects defined outside of the ElevatedPrivs calls, please note that the objects need to be created inside of the delegate.  You can check the MSDN site for reference, if you need to use the current context then use it to get the guid or the URL, and then create a new SPSite/SPWeb object inside of the delgate to work with.  It apparently does not work as the impersonation methods have in the past.

     

    Hope this helps.

     

    -DK

     

    Thursday, September 13, 2007 10:02 PM
  • Actually, the SPContext.Current property is probably returning the original context of the web request.  Try changing your code to this and see if you get any different results:

     

    Code Snippet

    SPSite site = SPContext.Current.Site;
    SPSecurity.RunWithElevatedPrivileges(delegate()
       {
          UserProfile u;
          using (SPSite elevatedSite = new SPSite(site.ID))
          {
             ServerContext context = ServerContext.GetContext(elevatedSite);
             UserProfileManager profileManager;
                   
             profileManager = new UserProfileManager(context,true);
             u = profileManager.GetUserProfile(m_user);
                   
             MembershipManager mgr = new MembershipManager(u);
                      
             Membership[] groups = mgr.GetItems();

             //do something here

          }

       }

    )

     

    Friday, September 7, 2007 12:24 PM
  • Fan-Fan - The compile error is probably occurring because your delegate method is empty. Try adding a line of code inside the delegate and see if it compiles.

     

    You shouldn't need to hardcode a user ID and password when using the RunWithElevatedPrivileges() method. Inside the delegate method, SharePoint will create objects under the context of an account which has full administrative privileges to the current web application (usually the LocalSystem account).

     

    Here's a C# code snippet for running code with elevated privileges. You need to make sure that all API objects are created starting from the "site" reference in the following code. Part of the example shows what to do if you already have a list or list item reference that is running with normal privileges.

     

    Code Snippet

    // Get references to the current site collection and site

    SPSite contextSiteCollection = SPContext.Current.Site;

    SPWeb contextSite = SPContext.Current.Web;

     

    // Get references to some API objects. These objects will still run

    // within the current user context even if you access them within the

    // RunWithElevatedPrivileges delegate method.

    SPList myList = contextSite.Lists["Documents"];

    SPListItem myListItem = myList.Items[0];

    SPFile myFile = myListItem.File;

    SPFolder myFolder = myFile.ParentFolder;

     

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

       // Get references to the site collection and site for the current context.

       // The using statement makes sures these references are disposed properly.

       using (SPSite siteCollection = new SPSite(contextSiteCollection.ID))

       {

          using (SPWeb site = siteCollection.OpenWeb(contextSite.ID))

          {

             // Allow "unsafe" operations (i.e. updating objects in the SharePoint site)

             site.AllowUnsafeUpdates = true;

     

             // Use the "site" reference to get new references to the other API objects.

             // These new references will run with elevated privileges.

             SPList elevatedList = site.Lists[myList.ID];

             SPListItem elevatedItem = site.GetListItem(myListItem.Url);

             SPFile elevatedFile = site.GetFile(myFile.UniqueId);

             SPFolder elevatedFolder = site.GetFolder(myFolder.UniqueId);

     

             //... perform additional operations here

          }

       }

    });

     

     

    Tuesday, September 11, 2007 1:30 PM

All replies

  •  

    It appears RunWithElevatedPrivileges runs as the app pool account. Your issue may lie with what rights are needed by the app pool account. You may try adding the app pool account to the Farm Administrators Group in operations.
    Friday, August 31, 2007 4:41 PM
  • Hi,
    Thanks for the reply. I added my app pool account to farm admins and also gave it all permissions in the SSP. However, I still get a 403.

    I am amazed that something so simple conceptually would be so difficult to achieve.

    Any other insight would be gratefully received.

    Mark
    Tuesday, September 4, 2007 8:54 AM
  • Is your app pool account the same as the app pool account for the ssp web application? You are basically doing a function which normally would be done from the ssp web application. Therefore, you may want to either change the app pool account to use the app pool account being used in the ssp or check to make sure the current app pool account has dbo rights to the ssp content database, read/write rights to all content databases associated  with the ssp, read rights to the configuration database and read rights for the central administration content database.

     

    Tuesday, September 4, 2007 1:54 PM
  • Hi SMC.
    I think I resolved the problem. I granted my own account "manage user profiles" in the SSP and was subsequently able to view my own memberships. I think I may have deployed the wrong assembly (ie one not using elevated privileges), so the process was running as me. I haven;t been able to test this properly yet, but thanks for your help so far.

    PS Sorry for the delay in replying, haven't been able to access this site from work so far this week.

    Mark
    Friday, September 7, 2007 7:34 AM
  • Can you post a code snippet? Usually when I've seen this problem it's because the code is using an SPSite or SPWeb reference that was determined before the privilege elevation. It's necessary to get a new SPSite reference inside the RunWithElevatedPrivileges delegate.

     

    • Proposed as answer by sujith sb Tuesday, March 30, 2010 1:42 PM
    Friday, September 7, 2007 11:10 AM
  • Hi David,
    I dont think that is the problem:

     

    Code Snippet

    SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    UserProfile u;
                    SPSite site = SPContext.Current.Site;
                    ServerContext context = ServerContext.GetContext(site);
                    UserProfileManager profileManager;
                  
                        profileManager = new UserProfileManager(context,true);
                        u = profileManager.GetUserProfile(m_user);
                  
                        MembershipManager mgr = new MembershipManager(u);
                     
                        Membership[] groups = mgr.GetItems(); 

    //do something here
    }

    From my previous posts, the UserProfileManager constructor has a bool parameter. If I call the overloaded method, I get a 403 in the browser and a permissions exception when debugging. The error is that the account needs "manage user profile permissions". I thought that I was using the elevated privileges call so I assumed that the thread would be running as the app pool account (the app pool being the default). I granted the app pool account the permissions in the SSP but this didn't result in success. I then granted my own account the same permissions and this time the code ran. This makes me think that I mistakenly installed a version *not* using elevated privileges, assuming that the IgnoreUserPrivacy setting would suffice.

    In the meantime, I developed what I shall call a hack, using the SSP database's stored procedures. I know, I know, but I'm on a tight deadline.

    Thanks for everyone's input...

    Mark
    Friday, September 7, 2007 11:54 AM
  • Actually, the SPContext.Current property is probably returning the original context of the web request.  Try changing your code to this and see if you get any different results:

     

    Code Snippet

    SPSite site = SPContext.Current.Site;
    SPSecurity.RunWithElevatedPrivileges(delegate()
       {
          UserProfile u;
          using (SPSite elevatedSite = new SPSite(site.ID))
          {
             ServerContext context = ServerContext.GetContext(elevatedSite);
             UserProfileManager profileManager;
                   
             profileManager = new UserProfileManager(context,true);
             u = profileManager.GetUserProfile(m_user);
                   
             MembershipManager mgr = new MembershipManager(u);
                      
             Membership[] groups = mgr.GetItems();

             //do something here

          }

       }

    )

     

    Friday, September 7, 2007 12:24 PM
  • Hi David,
    So, you are saying that SPContext.Current.Site when run within RunWithElevatedPrivileges uses the impersonating account?

    I am picking up from various posts that the call does not work as expected - is the behaviour documented somewhere?

    I can see that your code will work also, I am just surprised that mine doesn't.

    Thanks

    Mark
    Friday, September 7, 2007 4:59 PM
  • Hi there,

     

    I'm truly new to privilages problem (almost same problem as yours, i guess).

     

    Our sharepoint is using SSL, in App Pool>Identity we have hardcoded the username and password for authentication, instead of using "Network Services" as Identity.

     

    I had below sample codes, (I use VS Extension for WSS to write and upload to server):

    namespace User_Name

    {

    [Guid("d172ae1f-12f2-4706-ba17-b35e2663e9c8")]

    public class User_Name : System.Web.UI.WebControls.WebParts.WebPart

    {

    public User_Name()

    {

    }

     

    protected Label lblError;

    protected Button btnSave;

    protected TextBox txtWrite;

    ........

    protected override void CreateChildControls()

    {

    //******* label definition *******

    lblError = new Label();

    this.Controls.Add(lblError);

    //******* textbox definition *******

    txtWrite = new TextBox();

    txtWrite.Width = Unit.Pixel(260);

    txtWrite.Height = Unit.Pixel(22);

    txtWrite.TextMode = TextBoxMode.SingleLine;

    this.Controls.Add(txtWrite);

    //******* button definition ********

    btnSave = new Button();

    btnSave = "Save";

    btnSave.Click += new EventHandler(btnSave_Click);

    this.Controls.Add(btnSave);

    }

     

    protected override void Render(System.Web.UI.HtmlTextWriter writer)

    {

    ......................................

    }

     

    protected void btnSave_Click(object sender, EventArgs e)

    {

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

    ........... here are all the process ....................

    });

    }

     

    I'm trying to slot in below codes here and there, but don't know how to do it properly ...(or maybe still need more lines in between):

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

    });

     

    While compiling, it always prompts me below error:

    Attempted to perform an unauthorized operation

     

    Can I code it using hardcoded username and password (the one for App Pool). I guess the system needs this authorization programatically. If yes, how should i go about doing it?

    Can those codes on top be used for this purpose..?

     

    Thanks and Cheers........

    Tuesday, September 11, 2007 11:15 AM
  • Mah624, Sorry for the slow reply - I didn't get an alert notification for some reason,

     

    SPContext.Current.Site returns an SPSite reference that is running within the activation user context because it uses the HttpContext.Current property internally. Thus, it will be running using the identity of the impersonated user. You can verify the user identity by adding the following line of code and running the code with the debugger attached:

     

    Code Snippet

    Debug.WriteLine(SPContext.Current.Web.CurrentUser.LoginName);

     

     

    In almost all cases when you use the RunWithElevatedPrivileges method, you have to create a new SPSite reference within the delegate to execute SharePoint API calls with the elevated privilege account.

     

    Tuesday, September 11, 2007 12:37 PM
  • Fan-Fan - The compile error is probably occurring because your delegate method is empty. Try adding a line of code inside the delegate and see if it compiles.

     

    You shouldn't need to hardcode a user ID and password when using the RunWithElevatedPrivileges() method. Inside the delegate method, SharePoint will create objects under the context of an account which has full administrative privileges to the current web application (usually the LocalSystem account).

     

    Here's a C# code snippet for running code with elevated privileges. You need to make sure that all API objects are created starting from the "site" reference in the following code. Part of the example shows what to do if you already have a list or list item reference that is running with normal privileges.

     

    Code Snippet

    // Get references to the current site collection and site

    SPSite contextSiteCollection = SPContext.Current.Site;

    SPWeb contextSite = SPContext.Current.Web;

     

    // Get references to some API objects. These objects will still run

    // within the current user context even if you access them within the

    // RunWithElevatedPrivileges delegate method.

    SPList myList = contextSite.Lists["Documents"];

    SPListItem myListItem = myList.Items[0];

    SPFile myFile = myListItem.File;

    SPFolder myFolder = myFile.ParentFolder;

     

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

       // Get references to the site collection and site for the current context.

       // The using statement makes sures these references are disposed properly.

       using (SPSite siteCollection = new SPSite(contextSiteCollection.ID))

       {

          using (SPWeb site = siteCollection.OpenWeb(contextSite.ID))

          {

             // Allow "unsafe" operations (i.e. updating objects in the SharePoint site)

             site.AllowUnsafeUpdates = true;

     

             // Use the "site" reference to get new references to the other API objects.

             // These new references will run with elevated privileges.

             SPList elevatedList = site.Lists[myList.ID];

             SPListItem elevatedItem = site.GetListItem(myListItem.Url);

             SPFile elevatedFile = site.GetFile(myFile.UniqueId);

             SPFolder elevatedFolder = site.GetFolder(myFolder.UniqueId);

     

             //... perform additional operations here

          }

       }

    });

     

     

    Tuesday, September 11, 2007 1:30 PM
  • Hi,

     

    Thanks for your reply...

    Basically i'm not using SPList, SPListItem, SPFile and SPFolder....just SPSite and SPWeb.

    Do i need to do that?

    I adopt your codes to mine as below:

    FYI, this is for "button" execution part. Do i need to do the same to "Override" part?

     

    protected void btnExecuteSQL_Click(object sender, EventArgs e)

    {

    SPSite sViewUser = new SPSite("http://servername/");

    SPWeb wViewUser = sViewUser.OpenWeb();

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

    using (SPSite siteCollection = new SPSite(sViewUser.ID))

    {

    using (SPWeb site = siteCollection.OpenWeb(wViewUser.ID))

    {

    site.AllowUnsafeUpdates = true;

    DataSet dsViewUser = new DataSet();

    DataTable tViewUser = new DataTable();

    tViewUser.Columns.Add(new DataColumn("Name"));

    tViewUser.Columns.Add(new DataColumn("LoginID"));

    tViewUser.Columns.Add(new DataColumn("Group"));

    foreach (SPGroup gViewUser in site.SiteGroups)

    {

    foreach (SPUser uViewUser in gViewUser.Users)

    {

    string sGroup = gViewUser.Name;

    if (uViewUser.Name.ToLower() == txtSQL.Text.ToLower())

    {

    DataRow rViewUser = tViewUser.NewRow();

    rViewUser["Name"] = uViewUser.Name;

    rViewUser["LoginID"] = uViewUser.LoginName;

    rViewUser["Group"] = sGroup;

    tViewUser.Rows.Add(rViewUser);

    }

    }

    }

    this.gvResults.DataSource = tViewUser;

    this.gvResults.DataBind();

    }

    }

    });

    }

     

    It results me the same message as before, about the authorization. Do I need to elevate SPSite and SPWeb as well?

    Thanks in Advance....

     

    Wednesday, September 12, 2007 12:45 PM
  • One thing I have noticed in a couple of these posts is the SPContext is used or SPSite/SPWeb objects defined outside of the ElevatedPrivs calls, please note that the objects need to be created inside of the delegate.  You can check the MSDN site for reference, if you need to use the current context then use it to get the guid or the URL, and then create a new SPSite/SPWeb object inside of the delgate to work with.  It apparently does not work as the impersonation methods have in the past.

     

    Hope this helps.

     

    -DK

     

    Thursday, September 13, 2007 10:02 PM
  • Thanks David.. the discussion of this thread was helpful.
    Thursday, November 29, 2007 2:33 PM