Запрос Sharepoint с повышенными привилегиями

Веб-части требуется доступ к списку точек доступа (режим чтения). Если пользователь является администратором, проблем нет (работает должным образом), но если у пользователя нет разрешений на доступ, я должен использовать метод «RunWithElevatedPrivileges».

Проблема в том, что кажется, что запрос не возвращает правильные результаты. Что мне не хватает?

        SPList demoList = null;

        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            SPSite oSite = SPControl.GetContextSite(HttpContext.Current); // ADDED
            SPWeb oWeb = oSite.OpenWeb();                                 // ADDED
            demoList = oWeb.Lists["nameList"];
        });
        // demoList has 3 Elements (admin and no admin user) OK

        SPListItemCollection collListItems = null;

        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            SPQuery oQuery = new SPQuery() { Query = "<OrderBy><FieldRef Name='Date' Ascending='False' /></OrderBy>" };
            collListItems = demoList.GetItems(oQuery);
        });

        // 
        //IF ADMIN
        //collListItems.Count ==>3

        //IF NO ADMIN 
        //collListItems.Count ==>0

person Dr. No    schedule 18.05.2011    source источник


Ответы (3)


Вам нужно создать новый объект с повышенными привилегиями.

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    SPSite oSite = new SPSite(SPContext.Current.Site.ID); 
    SPWeb oWeb = oSite.OpenWeb(SPContext.Current.Web.ID);                                 
    demoList = oWeb.Lists["nameList"];
});

Кроме того, вы должны избавиться от вновь созданных объектов, и нет необходимости в двух делегатах.

SPSecurity.RunWithElevatedPrivileges(delegate {
    using (SPSite oSite =new SPSite(SPContext.Current.Site.ID))
    using (SPWeb oWeb = oSite.OpenWeb()) {
        var demoList = oWeb.Lists["nameList"];
        SPQuery oQuery = new SPQuery
                            { Query = "<OrderBy><FieldRef Name='Date' Ascending='False' /></OrderBy>" };
        SPListItemCollection collListItems = demoList.GetItems(oQuery);

        //IF ADMIN
        //collListItems.Count ==>3

        //IF NO ADMIN 
        //collListItems.Count ==>0
    }
});
person JWL_    schedule 18.05.2011
comment
Примечание: утечка объектов (например, возвращение SPList) из блока RunWithElevatedPrivileges может вызвать нефункциональный код или неожиданное повышение привилегий позже. Убедитесь, что вы не возвращаете объекты SPxxxx из делегата, переданного в RunWithElevatedPrivileges (или убедитесь, что все данные уже доступны в объекте). Имейте в виду, что возврат результатов запросов LINQ может отложить выполнение до более позднего момента и, как результат, выполнять вызовы SharePoint вне вызова RunWithElevatedPrivileges. - person Alexei Levenkov; 19.05.2011

Если вы создаете объекты Site и Web (или получаете к ним доступ из текущего SPContext) вне блока с повышенными правами, они будут иметь разрешения текущего пользователя, вошедшего в систему. Таким образом, ваш запрос, даже если он находится в блоке с повышенными правами, не использует повышенные разрешения. Вам необходимо создать новые объекты Site и Web внутри блока с повышенными правами, затем получить доступ к списку, а затем выполнить запрос, чтобы получить ожидаемые результаты.

Вот ресурс, который объясняет подробнее. Несмотря на то, что это было сделано для SharePoint 2007, это применимо к SharePoint 2010.

Выполнение команд с повышенными правами в Windows SharePoint Services 3.0 http://msdn.microsoft.com/en-us/library/bb466220(v=office.12).aspx

person Rob Windsor    schedule 18.05.2011
comment
Спасибо, но я добавил сайт и SpWeb (код изменен), но все еще не работает. - person Dr. No; 18.05.2011
comment
Вы получаете объект SPSite из контекста, поэтому к нему по-прежнему прикреплены учетные данные текущего пользователя. Чтобы получить повышенные привилегии, вам необходимо создать новый. - person Rob Windsor; 18.05.2011
comment
Еще одно замечание: вы создаете объект SPList с повышенными правами в одном блоке, а затем используете его в другом. Это может сработать (я сам никогда не пробовал), но я думаю, что было бы лучше объединить ваши два повышенных блока в один (как предлагает JWL). - person Rob Windsor; 18.05.2011

Если вы хотите включить операцию записи в список SharePoint, добавьте строку SPWeb.ValidateFormDigest() или SPUtility.ValidateFormDigest() перед методом RWEP.

SPUtility.ValidateFormDigest();
SPSecurity.RunWithElevatedPrivileges(delegate()
{

}
person Amay Kulkarni    schedule 04.07.2014