Почему RunWithElevatedPrivileges не выполняется? - PullRequest
3 голосов
/ 12 марта 2009

Я пытаюсь создать веб-часть, которая обрабатывает комментарии пользователей и сохраняет их в настраиваемом списке. Я написал этот код для добавления списка на сайт после добавления веб-части на страницу,

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    SPSite site = null;
    SPWeb web = null;

    public CommentWriteSpace()
    {
        SPSecurity.CodeToRunElevated foo = new SPSecurity.CodeToRunElevated(doit);

        SPSecurity.RunWithElevatedPrivileges(foo);
        SPListCollection listCollection = web.Lists;

        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        listCollection[listGuid].Fields.Add("User", SPFieldType.User, true);
        listCollection[listGuid].Fields.Add("Comment", SPFieldType.Text, true);
        listCollection[listGuid].OnQuickLaunch = true;
        listCollection[listGuid].Update();
        //this.Page.Request.Url.ToString()
    }

    public void doit()
    {
        site = SPContext.Current.Site;
        web = site.OpenWeb();
    }
}

Но метод RunWithElevatedPrivileges выдает исключение, я полагаю, это проблема с правами доступа, исключение такое же, как и при выполнении метода site.OpenWeb(); без повышения прав.

В чем может быть проблема?

Ответы [ 4 ]

4 голосов
/ 13 марта 2009

Вы видите ряд проблем:

  1. SPSite права доступа к объектам определяются при их создании, поэтому SPContext.Current.Site уже будет иметь разрешения текущего пользователя, даже если вы получите ссылку в пределах RWEP.
  2. Передача объектов SP из блока RWEP не поддерживается и, как правило, опасна. Если вам нужно использовать RWEP, все SPSite и SPWeb объекты (и их дочерние элементы), созданные в этом контексте, должны использоваться и располагаться в CodeToRunElevated.
  3. Каждый вызов listCollection[listGuid] создает новый объект SPList, который может вызвать непредвиденное поведение.

Как предполагает Дэн, RWEP не является предпочтительным методом для выполнения того, чего вы пытаетесь достичь. Используя расширение из link , на которое он ссылается, я бы переписал что-то вроде этого:

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    public CommentWriteSpace()
    {
        SPContext.Current.Site.RunAsSystem(UpdateSite);
        //this.Page.Request.Url.ToString()
    }

    public void UpdateSite(SPSite site)
    {
        SPWeb web = site.RootWeb;

        SPListCollection listCollection = web.Lists;
        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        SPList list = listCollection[listGuid];

        list.Fields.Add("User", SPFieldType.User, true);
        list.Fields.Add("Comment", SPFieldType.Text, true);
        list.OnQuickLaunch = true;
        list.Update();
    }
}
2 голосов
/ 12 марта 2009

Вам не нужно запускать SPContext.Current.Site с повышенными привилегиями. На самом деле, я думаю, именно поэтому вы получаете исключение. Кроме того, вы также можете использовать SPContext.Current.Web вместо site.OpenWeb (). Последний создает новый объект SPWeb, который вы будете нести ответственность за повторное удаление. Объекты SPSite и SPWeb из SPContext автоматически удаляются после завершения HTTP-запроса.

1 голос
/ 12 марта 2009

Я бы рекомендовал избегать использования RunWithElevatedPrivileges при взаимодействии с объектами SharePoint (где это возможно, как в вашем примере). Вы должны ограничить его использование только тогда, когда вам нужен доступ к ресурсам, которые находятся за пределами SharePoint (например, к базе данных, общей папке и т. Д.)

Вот отличная статья, в которой представлен очень элегантный подход к получению повышенных привилегий в контексте SharePoint: http://solutionizing.net/2009/01/06/elegant-spsite-elevation/

0 голосов
/ 12 марта 2009

Хм. Может быть, было бы проще просто выполнить большую часть вашего кода в анонимном делегате?

SPSecurity.RunWithElevatedPrivileges(delegate()
{
  // Your code here
}

Вероятно, также лучше создать объект SPList, чем неоднократно обращаться к коллекции. Некоторые эти коллекции ведут себя немного странно - я думаю, что SPViewCollection создает новый объект каждый раз, когда вы получаете к нему доступ через guid / index!

Все эти вопросы, я согласен с Ларсом - используйте SPContext.Current.Web

...