在 SharePoint 中配置项目级安全
了解在 SharePoint 中,如何在使用 BCS 索引连接器对外部数据进行爬网时配置项目级安全。
具有 NTLM 身份验证的外部系统
对于支持 NTLM 身份验证的外部系统来说,可以在爬网时间为外部内容类型的每个实例获取安全描述符,并将其存储在内容索引中。 在查询期间,把正在提交搜索查询的用户的安全描述符与存储的安全描述符相比较,以确定该用户是否可以对该项进行访问。 这是在结果集中执行安全修整的最快方式。 外部系统的元数据模型必须指示在什么地方可以发现安全描述符为外部内容类型或方法。
外部内容类型字段
如果使用 WindowsSecurityDescriptorField 属性对包含该描述符的外部内容类型字段进行了标记,则 Microsoft SharePoint 将存储该安全描述符(如以下示例所示)。
<Method Name="Item SpecificFinder ">
<Properties>
<Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property>
<Property Name="RdbCommandText" Type="System.String">SELECT [Identifier] ,
[SecurityDescriptor] FROM [Test].[dbo].[Items] WHERE [Identifier] = @Identifier</Property>
<Property Name="BackEndObjectType" Type="System.String">SqlServerTable</Property>
<Property Name="BackEndObject" Type="System.String">Items</Property>
<Property Name="Schema" Type="System.String">dbo</Property>
</Properties>
<Parameters>
<Parameter Direction="In" Name="@Identifier">
<TypeDescriptor TypeName="System.Int32" IdentifierName="Identifier" Name="Identifier" />
</Parameter>
<Parameter Direction="Return" Name="BaseItemsRead Item">
<TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="BaseItemsRead Item">
<TypeDescriptors>
<TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="BaseItemsRead ItemElement">
<TypeDescriptors>
<TypeDescriptor TypeName="System.Int32" IdentifierName="Identifier" Name="Identifier"/>
<TypeDescriptor TypeName="System.Byte[], mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="SecurityDescriptor">
<TypeDescriptors>
<TypeDescriptor TypeName="System.Byte" Name="SecurityDescriptorElement" />
</TypeDescriptors>
</TypeDescriptor>
</TypeDescriptors>
</TypeDescriptor>
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Type="SpecificFinder" ReturnParameterName="BaseItemsRead Item"
ReturnTypeDescriptorName="BaseItemsRead ItemElement" Name="BaseItemsRead Item"
DefaultDisplayName="ReadSecurity">
<Properties>
<Property Name="WindowsSecurityDescriptorField" Type="System.String">
SecurityDescriptor
</Property>
</Properties>
</MethodInstance>
</MethodInstances>
</Method>
注意
缓存项不能超过指定大小,而访问控制列表很容易就会超过。 因此,如果缓存项包含安全描述符字段,搜索连接器框架就会忽略向缓存项发出的请求。
外部内容类型方法
如果您在基于其标识符返回项的安全描述符的元数据模型中定义了方法,则您可以使用 BinarySecurityDescriptorAccessor 构造型(如以下示例所示)。
<Method Name="GetItemSecurity" LobName="GetItemSecurity">
<Parameters>
<Parameter Name="itemId" Direction="In">
<TypeDescriptor Name="itemId" TypeName="System.Int32, mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
IdentifierEntityNamespace="MS.Internal.Test.Automation.Search.Scater"
IdentifierEntityName="Item" IdentifierName="ItemId" />
</Parameter>
<Parameter Name="Return" Direction="Return">
<TypeDescriptor Name="SecurityDescriptor" TypeName="System.Byte[],
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
IsCollection="true">
<TypeDescriptors>
<TypeDescriptor Name="Item" TypeName="System.Byte, mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="GetItemSecurity_Instance" Type="BinarySecurityDescriptorAccessor"
ReturnParameterName="Return" ReturnTypeDescriptorName="SecurityDescriptor"
ReturnTypeDescriptorLevel="0">
<Properties>
<Property Name="WindowsSecurityDescriptorField" Type="System.String">
SecurityDescriptor
</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="NT AUTHORITY\\Authenticated Users">
<Right BdcRight="Execute" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
以下代码是上一个示例中指定的方法的方法签名。
Public static Byte[]GetItemSecurity (string id)
{
}
具有可以映射到 NTLM 身份验证的身份验证方案的外部系统
如果该外部系统不支持 NTLM 身份验证,但是可以使用映射表将外部系统用户映射到 Windows 用户,那么您将可以使用上两个代码示例中描述的方法来提供项目级安全。 为了让此工作,外部系统揭示的 Web 服务或 Windows Communication Foundation (WCF) 服务必须包括这样一种方法,使用这种方法可以将外部系统用户内部转换为 Windows 用户,然后为每个 URL 返回 Windows 安全描述符。 以下示例演示了您如何针对此方法进行编码。
/// Returns the security descriptor for a user.
/// </summary>
/// <param name="domain"></param>
/// <param name="username"></param>
/// <returns></returns>
private Byte[] GetSecurityDescriptor(string domain, string username)
{
NTAccount acc = new NTAccount(domain, username);
SecurityIdentifier sid = (SecurityIdentifier)acc.Translate(typeof(SecurityIdentifier));
CommonSecurityDescriptor sd = new CommonSecurityDescriptor(false, false, ControlFlags.None,
sid, null, null, null);
sd.SetDiscretionaryAclProtection(true, false);
//Deny access to all users.
SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
sd.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, everyone,
unchecked((int)0xffffffffL), InheritanceFlags.None, PropagationFlags.None);
//Grant full access to a specified user.
sd.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid,
unchecked((int)0xffffffffL), InheritanceFlags.None, PropagationFlags.None);
byte[] secDes = new Byte[sd.BinaryLength];
sd.GetBinaryForm(secDes, 0);
return secDes;
}