站点集中的隐藏列表权限丢失导致的子站点创建失败
问题描述
前些天收到一个用户提出的故障,情况是这样的:
在他的站点中,只要他创建站点,不管用什么模板就会报错,报错信息如下图:
然后通过Correlation ID查找ULS Log发现了下面的错误信息:
Detected use of SPRequest for previously closed SPWeb object. Please close SPWeb objects when you are done with all objects obtained from them, but not before.
Stack trace:
at Microsoft.SharePoint.WebControls.ScriptLink.SharePointClientJs_Register(Page page)
at Microsoft.SharePoint.WebControls.ScriptLink.InitJs_Register(Page page)
at Microsoft.SharePoint.WebControls.ScriptLink.RegisterForControl(Control ctrl, Page page, String name, Boolean localizable, Boolean defer, Boolean loadAfterUI, String language)
at Microsoft.SharePoint.WebControls.ScriptLink.Register(Page page, String name, Boolean localizable, Boolean defer, Boolean loadAfterUI, String language, String uiVersion)
at Microsoft.SharePoint.WebControls.ScriptLink.RegisterOnDemand(Page page, String strKey, String strFile, Boolean localizable)
at Microsoft.SharePoint.WebControls.ScriptLink.RegisterCore(Page page, Boolean defer)
at Microsoft.SharePoint.WebPartPages.SPWebPartManager.RegisterOWSScript(Page page, SPWeb web)
at Microsoft.SharePoint.WebPartPages.WebPartPage.FormOnLoad(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP._layouts_addgallery_aspx.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr managedHttpContext, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr managedHttpContext, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr managedHttpContext, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr managed
解决过程
根据这个信息看来,貌似是什么代码在释放SPWeb实例过于提前了,后来的调用就出了错,但经过反复的排查都没找到哪里的代码有问题,很是奇怪。
后来在同事的提醒下注意到一个现象,就是用Farm Admin账号在这个站点集里创建子站点是没有问题的,但是如果只有Full Control就不行。。这就说明问题的根源很可能还是跟权限有关。
最后经过排查终于发现原来是这个站点集中的很多隐藏列表的权限出了问题。比如TaxonomyHiddenList和MasterPageGallery这两个隐藏列表,他们都是拥有独立权限的列表而且没有给任何人赋予权限。。那就难怪会有问题了,因为创建子站点的过程中SharePoint需要使用用户的权限到这几个隐藏列表中取数据,没有权限自然会出问题。
那么解决的方法也很简单,通过使用下面这段代码把出问题的站点的隐藏列表权限全部列出, 再用它导出另外一个完全正常的站点的权限设置, 两相对比之后就可以发现具体哪几个隐藏列表的权限不对,缺少了哪几个用户的权限,最后再手动添加就可以了。
下面的这段powershell代码可以列出一个站点中所有隐藏列表的权限设置。
1 $siteurl = Read-Host 2 $web = Get-SPWeb -Identity $siteurl 3 #Start-Transcript -Path GetHiddenListsInfo.txt -Force 4 cls 5 Write-Host 6 write-Host "Site Url: "$siteurl 7 $lists = $web.lists | ? { 8 ($_.Hidden -eq $true) -and ($_.Hasuniqueroleassignments -eq $true) 9 } 10 Write-Host "List Count: "$lists.Count 11 12 $lists | foreach { 13 Write-Host 14 Write-Host "---------------------" 15 write-host $_.Title 16 Write-Host "---------------------" 17 $_.Permissions | foreach { 18 $_.Member.Name 19 } 20 Write-Host "=====================" 21 } 22 23 #Stop-Transcript