如果以提升的权限运行,普通用户是否可以更新 SPPersistedObject 设置?
-
10-12-2019 - |
题
我有一个自定义功能区图标“Enlist”部署到每个文档库。正常(即非管理员)用户可以单击此图标;当他这样做时,我想将文档库信息(ID、名称)永久保存在某个地方。然后,中央管理员可以(通过自定义中央管理页面)查看用户登记的所有文档库的列表。
我正在考虑使用 SPPersistedObject
当用户单击功能区图标时存储文档库信息。但是,据我所知,这需要农场管理员权限,这意味着普通用户在单击“登记”时会遇到错误。 运行具有提升权限的写入 SPPersistedObject 的代码是否可以解决此问题, ,或者仍然会发生错误吗?这就是我的意思:
// Execute this code when a ribbon icon is clicked by a normal user
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// Write DocumentLibrary Id and Name to some custom SPPersistedObject
});
MSDN 是这么说的 RunWithElevatedPrivileges()
“在应用程序池身份下运行,该标识在该应用程序池托管的所有站点收集中具有站点收集管理员特权。”这足以更新 SPPersistedObject
?
我应该覆盖吗 SPPersistedObject.HasAdditionalUpdateAccess
总是返回 true,或者这对于特权最少的环境来说仍然不够吗?如果不是,除了自定义数据库之外,我还可以选择哪些选项来存储此类信息?
解决方案
提升权限不足以写入配置 数据库通过提升权限,您可以使用网络 应用程序池的标识,它只有读取 配置数据库。当然,管理员用户(运行中央 管理员应有读写权限)。
SPPersistedObject.HasAdditionalUpdateAccess
仍然需要将非场管理员用户模拟为场管理员用户。
最后一个需要讨论的主题是安全性。如所述 之前,农场配置数据库中存在 HOS。严格 说起来,它的存在是为了支持行政管理功能,但它 其用途超出了这一范围。例如,如果我们要创建一个自定义的 定时器工作,我们希望能够将任务提交给我们的工作 完成。这些任务最有可能源自 在非行政范围内。可能是由于用户 点击其他站点集合的网络部件上的按钮。与 在以前的 SharePoint 版本中,这根本不可能实现。只有 农场管理员可以更新 HOS。然而,对于 SharePoint 2010 年,在基本 SPPersistedObject 中增加了以下内容 向其他用户开放居屋。我们可以修改 我们的主要功能如下
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace PersistedObjectDemo
{
internal class Program
{
private const int LOGON_TYPE_INTERACTIVE = 2;
private const int LOGON_TYPE_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool LogonUser(string userName, string domain, string password, int logonType,
int logonProvider, ref IntPtr accessToken);
private static void Main(string[] args)
{
try
{
IntPtr accessToken = IntPtr.Zero;
if (LogonUser("non-farm-admin-username", "your-domain-name", "your-password", LOGON_TYPE_INTERACTIVE,
LOGON_TYPE_PROVIDER_DEFAULT, ref accessToken))
{
using (var identity = new WindowsIdentity(accessToken))
{
using (identity.Impersonate())
{
MyPersistedObject obj = MyPersistedObject.Local;
//delete existing object and recreate to keep things simple
obj.Delete();
obj = MyPersistedObject.Local;
obj.Foo = "Some updated value";
obj.Update();
}
}
}
}
catch (Exception ex)
{
Console.Write(ex);
}
Console.WriteLine("Press return to exit");
Console.ReadLine();
}
}
}
该代码模拟了非农场管理员用户更新HOS的尝试。如果我们运行此操作,我们将看到以下异常,这是我们的陷阱3:
系统.安全.安全异常:拒绝访问。于 Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate() at PersistedObjectDemo.MyPersistedObject.Update()
不出所料,使用非农场管理员用户更新居屋计划 就会出现异常。但是,如果我们在 MyPersistedObject.cs 并再次运行我们的程序,我们可以看到 适当更新居者有其屋计划。
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
当然,在实际应用中,我们可能需要添加一些 安全检查,而不是简单地返回 true 并允许任何人更新我们的对象,但希望这 充分说明了这一点。
在安全方面还有一个问题--当 SharePoint 默认情况下,只有农场管理员账户具有读/写权限。 访问配置数据库。在最小权限安装中,所有 除中央管理程序外,网络应用程序将运行 在自己的服务帐户下,这些帐户将不具有写入功能。 访问配置数据库。因此,添加、删除和 这样就无法更新 HOS 中的对象。尽管 HasAdditionalUpdateAccess 允许我们对谁可以 更新 HOS,如果底层应用程序池账户没有 适当的数据库权限。 很快。