信任设置为完全,但 Web 部件仍然导致 SecurityException

发布于 2024-08-24 09:02:07 字数 2108 浏览 8 评论 0原文

我有一个访问 SP 对象模型的 Web 部件,该部件打包在已签名并部署到 GAC 的程序集中。 web.config 设置为“完全”信任,但我的 Web 部件抛出 SecurityException。有问题的代码行:

SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(() =>
{
    foreach (SPGroup g in user.Groups)
    {
        identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(@"\", @"\\"));
    }
}));

调用 RunWithElevatedPrivileges 时似乎会引发异常(换句话说,我的委托根本不执行)。有什么想法吗?此时我完全困惑了。

更新:这是在将代码包装到 RunWithElevatedPrivileges 方法之前的样子:

public MyWebPart()
{            
    context = new MyProject.Data.MyDataContext(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString);
    SPUser user = SPContext.Current.Web.CurrentUser;
    identity = String.Format("'{0}'", user.LoginName.ToLowerInvariant().Replace(@"\", @"\\"));
    foreach (SPGroup g in user.Groups)
    {
        identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(@"\", @"\\"));
    }            

    identity = '[' + identity + ']';
}

异常:

System.Security.SecurityException occurred
  Message="Request failed."
  Source="Microsoft.SharePoint"
  StackTrace:
       at Microsoft.SharePoint.SPBaseCollection.System.Collections.IEnumerable.GetEnumerator()
       at MyProject.MyWebPart..ctor()
  InnerException: 

根据异常帮助程序提供的突出显示,它看起来像是尝试访问 SPUser.Groups 属性问题是:user.Groups

让我真正困惑的是,这个确切的代码两天前工作正常,但我的农场遇到了一些其他问题,基本上不得不重建它。再次恢复所有其他内容后,我尝试将此 Web 部件添加到页面中,并且出现了此问题。我尝试将代码包装在 RunWithElevatedPrivileges 包装器中,看看是否可以准确隔离有问题的位,但看起来任何接触 SP 对象模型的内容都会导致异常,包括 RunWithElevatedPrivileges代码>方法。

update2:我仍然不知道失败的真正原因,但它是在我尝试添加 Web 部件时发生的。在调试器中设置断点后,我意识到构造函数被调用了两次;第一次,一切都按预期工作,但第二次是抛出异常时。我还是不知道为什么。我找到了解决此问题的两种方法:将有问题的代码从构造函数移到 Web 部件生命周期的稍后位置,或者注释掉代码以添加 Web 部件,然后取消注释并重新部署。

显然,这个“3天前工作”的原因是因为我很久以前就将我的Web部件添加到了页面,然后将上面的代码添加到了构造函数中。由于 Web 部件已经添加,所以我从未发现任何问题。后来,当我最近不得不重建网站并将Web部件再次添加到页面时,这个问题就显现出来了。所以从技术上来说,它之前并没有“工作”,我只是没有做让它行为不端的事情。

不管怎样,就像我说的 - 我仍然不知道异常的真正原因,所以仍然欢迎类似的答案。

I've got a web part that accesses the SP object model, packaged in an assembly which is signed and deployed to the GAC. The web.config is set for "Full" trust, and yet my web part throws a SecurityException. The offending lines of code:

SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(() =>
{
    foreach (SPGroup g in user.Groups)
    {
        identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(@"\", @"\\"));
    }
}));

It appears that the exception is thrown when RunWithElevatedPrivileges is called (in other words, my delegate doesn't execute at all). Any ideas? I'm completely bewildered at this point.

update: here's what the code looked like before I wrapped it in the RunWithElevatedPrivileges method:

public MyWebPart()
{            
    context = new MyProject.Data.MyDataContext(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString);
    SPUser user = SPContext.Current.Web.CurrentUser;
    identity = String.Format("'{0}'", user.LoginName.ToLowerInvariant().Replace(@"\", @"\\"));
    foreach (SPGroup g in user.Groups)
    {
        identity += String.Format(",'{0}'", g.Name.ToLowerInvariant().Replace(@"\", @"\\"));
    }            

    identity = '[' + identity + ']';
}

And the exception:

System.Security.SecurityException occurred
  Message="Request failed."
  Source="Microsoft.SharePoint"
  StackTrace:
       at Microsoft.SharePoint.SPBaseCollection.System.Collections.IEnumerable.GetEnumerator()
       at MyProject.MyWebPart..ctor()
  InnerException: 

Based on the highlight provided by the exception helper, it looks like the attempted access of the SPUser.Groups property is the problem: user.Groups.

What's got me really confused is that this exact code was working fine two days ago, but I had some other problems with the farm and basically had to rebuild it. After getting everything else back up again, I went and tried to add this web part to a page and this problem manifested itself. I tried wrapping the code in the RunWithElevatedPrivileges wrapper to see if I could isolate exactly the offending bit, but it looks like anything that touches the SP oject model causes the exception, including the RunWithElevatedPrivileges method.

update2: I still don't know the real reason this was failing, but it was happening when I was trying to add the web part. After setting breakpoints in the debugger, I realized that the constructor was being called twice; the first time, it all worked exactly as expected, but the second time was when the exception was being thrown. I still have no idea why. I found two ways around this: move the offending code out of the constructor into a later point in the lifecycle of the web part, or comment out the code to add the web part, then uncomment it and redeploy.

Apparently, the reason this "worked 3 days ago" was because I had added my web part to a page a long time ago, and then added the above code to the constructor. Since the web part was already added, I never saw any problems. Later, when I recently had to rebuild the site and add the web part to the page again, this problem manifested itself. So technically, it didn't "work" before, I just wasn't doing the thing that made it misbehave.

Anyway, like I said - I still don't know the true cause of the exception, so answers along those lines are still welcome.

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

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

发布评论

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

评论(1

青萝楚歌 2024-08-31 09:02:07

如果您尝试使用在 RunWithElevatedPrivileges() 方法之外创建的 SharePoint 对象,因此仍保留其旧的安全上下文,则可能会出现此问题。在您的情况下,您使用的 SPUser 对象不是在 RunWithElevatedPrivileges() 方法中创建的。

要解决此问题,您应该在委托中创建要使用的对象。委托外部的安全 ID 或 URL,用于重新创建对象。例如:保护 SPSite 对象的 URL 或 ID,并使用它在委托中再次创建它。

 public void Demo()
 {
      string  siteURL = SPContext.Current.Site.Url;
      SPSecurity.RunWithElevatedPrivileges(delegate(){

          using (SPSite safeSite = new SPSite(siteURL))
          {
             // place your code here ... 
          }
      });
  }

也许您可以发布堆栈跟踪,以便我们可以获得更多信息。

The problem could occur if you try to work with SharePoint objects which were created outside of the RunWithElevatedPrivileges() method, and therefore still hold their old security context. In your case you use a SPUser object which was not created within the RunWithElevatedPrivileges() method.

To work around, you should create the object you want to work with within the delegate. Safe Ids or URLs outside of the delegate, to use them for recreating the objects. E.g.: safe the URL or ID of a SPSite object and use it to create it again within the delegate.

 public void Demo()
 {
      string  siteURL = SPContext.Current.Site.Url;
      SPSecurity.RunWithElevatedPrivileges(delegate(){

          using (SPSite safeSite = new SPSite(siteURL))
          {
             // place your code here ... 
          }
      });
  }

Perhaps you could post the stack trace so we can get some more information.

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