从 Web 部件更新 SPPersistedObject 时出错
我在 SharePoint 2007 中编写了两个功能。 一个的范围是网站级别,它基本上将一个 Web 部件添加到激活它的网站集中。 该功能组件部署在“bin”目录下。 第二个是 Farm 范围,它是我的自定义 SPPersistedObject,部署在管理中心。 该程序集已添加到 GAC 中。
我需要从 Web 部件更新我的自定义对象。 这在大多数情况下工作得很好。 但在一些遵循最小权限管理域帐户的服务器上' http://technet.microsoft.com/en-us/library/cc263445。 aspx' 我收到以下错误
系统.Security.SecurityException: 拒绝访问。 在 Microsoft.SharePoint.Administration.SPPersistedObject.Update() 在 MyWebPart。<>c__DisplayClass1.b__0() 在 Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(对象 状态)在 Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.b__2() 在 Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated) 安全代码)位于 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode,对象参数)位于 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated 安全代码)位于 MyWebPart.RenderWebPart(HtmlTextWriter 作者)集会的区域 失败的是:我的电脑
我是否需要设置任何权限或 CAS 策略来防止此错误?
以下是我当前为 Web 部件组装设置的 CAS 策略。 我需要在这里做任何改变吗?
<CodeAccessSecurity>
<PolicyItem>
<PermissionSet class="NamedPermissionSet" version="1" Name="MyPermission" Description="Permission set for my solution">
<IPermission class="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Level="Medium" />
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
<IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="AllFlags" />
<IPermission class="Microsoft.SharePoint.Security.WebPartPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" Connections="true" />
<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" ObjectModel="true" UnsafeSaveOnGet="true" Impersonate="true"/>
<IPermission class="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true">
<ConnectAccess>
<URI uri="$OriginHost$"/>
<URI uri="http://.*\.xyz\.com/.*"/>
</ConnectAccess>
</IPermission>
</PermissionSet>
<Assemblies>
<Assembly Name="MyWebPart" Version="1.0.0.0" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100df0e85cb8c660241cd3225eb653a590b91303ddbd37f8f1e661d2dffb840a258b899d6bacbbc55d03768d5ea0260ee4c8341fd447d7200abdb74b837733c3f756833e169cae803aef808530dd3ddad953a49492faee3eeba6f0dba66b0d66f1f9ca5266c69dcb799ed364db5e9e6ebcd4e81fb27365de962cbe6e7e7fba300dc"/>
</Assemblies>
</PolicyItem>
</CodeAccessSecurity>
请指教。
问候, 贾格纳特
I have written two features in SharePoint 2007.
One is scoped at Site level and it basically adds a web part to the site collection where it is activated. This feature assembly is deployed under the 'bin' directory.
Second is Farm scoped which is my custom SPPersistedObject and is deployed in Central Administration. The assembly is added to GAC.
From the web part I need to update my custom object. This is working fine in most cases. But on some servers that follow the least privilege administration domain accounts '
http://technet.microsoft.com/en-us/library/cc263445.aspx' I am getting the below error
System.Security.SecurityException:
Access denied. at
Microsoft.SharePoint.Administration.SPPersistedObject.Update()
at MyWebPart.<>c__DisplayClass1.b__0()
at
Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object
state) at
Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.b__2()
at
Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated
secureCode) at
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback
secureCode, Object param) at
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated
secureCode) at
MyWebPart.RenderWebPart(HtmlTextWriter
writer) The Zone of the assembly that
failed was: MyComputer
Do I need to set any permissions or CAS policies to prevent this error?
Below is my current CAS policy set for the web part assembly. Do I need to make any changes here.
<CodeAccessSecurity>
<PolicyItem>
<PermissionSet class="NamedPermissionSet" version="1" Name="MyPermission" Description="Permission set for my solution">
<IPermission class="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Level="Medium" />
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
<IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="AllFlags" />
<IPermission class="Microsoft.SharePoint.Security.WebPartPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" Connections="true" />
<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" ObjectModel="true" UnsafeSaveOnGet="true" Impersonate="true"/>
<IPermission class="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true">
<ConnectAccess>
<URI uri="$OriginHost$"/>
<URI uri="http://.*\.xyz\.com/.*"/>
</ConnectAccess>
</IPermission>
</PermissionSet>
<Assemblies>
<Assembly Name="MyWebPart" Version="1.0.0.0" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100df0e85cb8c660241cd3225eb653a590b91303ddbd37f8f1e661d2dffb840a258b899d6bacbbc55d03768d5ea0260ee4c8341fd447d7200abdb74b837733c3f756833e169cae803aef808530dd3ddad953a49492faee3eeba6f0dba66b0d66f1f9ca5266c69dcb799ed364db5e9e6ebcd4e81fb27365de962cbe6e7e7fba300dc"/>
</Assemblies>
</PolicyItem>
</CodeAccessSecurity>
Please advice.
Regards,
Jagannath
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Jagannath,
您遇到的问题是由于 SPPersistedObject 派生类型的数据的后备存储是 SharePoint 场配置数据库。 在最低权限安装中,唯一具有对此数据库的读取访问权限以外的任何权限的帐户是场服务(计时器服务)帐户。 即使提升代码中的权限也只会将您的安全上下文“提升”到站点在 IIS 中运行的应用程序池帐户的安全上下文。
我以前遇到过您遇到的情况,并且我只知道解决该问题的两种方法:
找到一种在场服务帐户上下文中运行应用程序代码的方法。 这通常意味着将代码作为自定义计时器作业运行。
调整场配置数据库权限以授予应用程序池帐户(假设在作为提升的安全块的一部分运行时)写入访问权限。
调整场配置数据库权限以授予应用程序
在这两个选项中,只有第一个选项符合“最小权限”执行原则……但它确实需要重新构建代码。
我通常很好地创建了一个“扫描”自定义计时器作业,该作业被创建并计划在功能激活时运行。 然后,该计时器作业检查网站集(通常扫描整个 Web 应用程序)以查看是否需要保留、更新属性等。如果发现需要更新,则由计时器作业执行更新,因为它具有所需的访问权限等级。
我所描述的示例出现在我在 CodePlex 上发布的功能中 (http ://blobcachefarmflush.codeplex.com/SourceControl/changeset/view/53851#797787)。 我需要更新 SPWebApplication 实例上的属性包,而执行此操作的唯一方法是在计时器作业的上下文中。 当用户在 UI 中进行更改时,会在网站集 RootWeb 的 Properties 集合上设置一个标志。 计时器作业扫描网站集,当它看到这样的标志集时,它会根据适当的安全上下文进行必要的更改。
我希望这有帮助!
Jagannath,
The problem you're encountering is due to the fact that the backing store for the data from SPPersistedObject-derived types is the SharePoint farm configuration database. In a least privileges installation, the only account that has anything other than read access to this database is the farm service (timer service) account. Even elevating privileges in your code is only going to "raise" your security context to that of the application pool account under which the site is running within IIS.
I've encountered the situation you're in before, and I'm only aware of two ways to work around it:
Find a way to run your application code within the context of the farm service account. This normally translates to running the code as a custom timer job.
Adjust the farm configuration database permissions to grant the application pool account (assumed when run as part of an elevated security block) write access.
Of these two options, only the first option stays true to the "least privileges" principle of execution ... but it does entail re-architecting your code.
I've generally had good creating a "sweep" custom timer job that gets created and scheduled to run at Feature activation time. That timer job then checks the site collection (typically sweeping an entire web application) to see if properties need to be persisted, updated, etc. If it finds updates are necessary, they are carried out by the timer job since it has the required access level.
An example of what I'm describing appears in a Feature I put out on CodePlex (http://blobcachefarmflush.codeplex.com/SourceControl/changeset/view/53851#797787). I needed to update the Properties bag on an SPWebApplication instance, and the only way to do so was from within the context of a timer job. When a user makes changes from within the UI, a flag gets set on Properties collection of the site collection's RootWeb. The timer job sweeps through the site collection, and when it sees such a flag set, it takes care of making the necessary changes from the appropriate security context.
I hope this helps!