为什么 RunWithElevatedPrivileges 执行失败?

发布于 2024-07-15 03:06:39 字数 1183 浏览 6 评论 0原文

我正在尝试制作一个 Web 部件,用于 grep 用户评论并将其存储在自定义列表中,我编写了此代码,以便在将 Web 部件添加到页面后将列表添加到网站,

[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(); 方法时出现的异常相同。

可能是什么问题呢?

I'm trying to make a web part that greps user comments and stores it in custom list, I wrote this code to add a list to the site once the web part added to the page,

[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();
    }
}

But the RunWithElevatedPrivileges method throw an exception, I guess it's a permission issue, the exception is the same as one appears when executing site.OpenWeb(); method without elevating privileges.

What could be the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我的奇迹 2024-07-22 03:06:39

您看到了许多问题:

  1. SPSite 对象权限是在创建时确定的,因此 SPContext.Current.Site 将已经拥有当前用户的权限,即使您可以在 RWEP 中获得参考。
  2. 从 RWEP 块中传递 SP 对象是不受支持的,而且通常很危险。 如果您确实需要使用 RWEP,则应使用在该上下文中创建的所有 SPSiteSPWeb 对象(及其子对象)并在 CodeToRunElevated 中进行处置>。
  3. 每次调用 listCollection[listGuid] 都会创建一个新的 SPList 对象,这可能会导致意外行为。

正如 Dan 所建议的,RWEP 并不是实现您想要完成的任务的首选方法。 使用他引用的 链接 中的扩展,我将重写为看起来像这样:

[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();
    }
}

You're seeing a number of problems:

  1. SPSite object permissions are determined when they are created, so SPContext.Current.Site will already have the permissions of the current user even if you get the reference within RWEP.
  2. Passing SP objects out of a RWEP block is unsupported and generally dangerous. If you do need to use RWEP, all SPSite and SPWeb objects (and their children) created within that context should be used and disposed in the CodeToRunElevated.
  3. Each call to listCollection[listGuid] will create a new SPList object, which may cause unexpected behavior.

As Dan suggests, RWEP is not the preferred method to do what you're trying to accomplish. Using an extension from the link he references, I would rewrite to look something like this:

[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();
    }
}
凹づ凸ル 2024-07-22 03:06:39

您无需以提升的权限运行 SPContext.Current.Site。 事实上,我认为这就是你得到例外的原因。 此外,您还可以使用 SPContext.Current.Web 而不是 site.OpenWeb()。 后者创建一个新的 SPWeb 对象,您将负责再次处理该对象。 HTTP 请求完成后,SPContext 中的 SPSite 和 SPWeb 对象将自动释放。

There is no need for you to run SPContext.Current.Site with elevated privileges. In fact, I think this is why you get the exception. Furthermore, you could also use SPContext.Current.Web instead of site.OpenWeb(). The latter creates a new SPWeb object that you will be responsible of disposing again. SPSite and SPWeb objects from SPContext are automatically disposed when the HTTP request has completed.

盗心人 2024-07-22 03:06:39

我建议在与 SharePoint 对象交互时避免使用 RunWithElevatedPrivileges(只要可能,就像在您的示例中一样)。 您应该将其使用限制在需要访问 SharePoint 外部的资源(例如数据库、文件共享等)时。

这是一篇优秀的文章,它提供了一种非常优雅的方法来在 SharePoint 上下文中获取提升的权限:
http://solutionizing.net/2009/01/06/elegant-spsite -海拔/

I would suggest avoiding using RunWithElevatedPrivileges when interacting with SharePoint objects (wherever possible, like in your example). You should restrict its use to when you need to access resources that are outside SharePoint (for example a database, file share, etc.)

Here is an excellent article that provides a very elegant approach to getting elevated privileges within a SharePoint context:
http://solutionizing.net/2009/01/06/elegant-spsite-elevation/

踏月而来 2024-07-22 03:06:39

唔。 在匿名委托中运行大部分代码可能会更容易吗?

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

创建 SPList 对象可能比重复访问集合更好。 有些集合的行为有点奇怪 - 我认为 SPViewCollection 在每次通过 guid/index 访问它时都会创建一个新对象!

所有这些问题,我同意 Lars 的观​​点 - 使用 SPContext.Current.Web

Hmm. Would it maybe be easier to just run the bulk of your code in an anonymous delegate?

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

It's probably also better to create an SPList object, rather than accessing the collection repeatedly. Some those collections behave a little strangely - I think it's the SPViewCollection create a new object each time you access it via a guid/index!

All of that askice, I agree with Lars - use SPContext.Current.Web

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文