SharePoint でアイテム レベルのセキュリティを構成する

SharePoint で BCS インデックス コネクタを使用して外部データをクロールする際に、アイテム単位でセキュリティを設定する方法を説明します。

重要

Business Connectivity Services (BCS) と NTLM ベースの構成は、主に SharePoint Server でサポートされています。 これらの方法は、最新の認証と Microsoft Graph ベースのコネクタが推奨される SharePoint Online では一般的に使用されません。

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>

注:

項目は特定のサイズに制限されており、アクセス制御リスト (ACL) を簡単に超える可能性があります。 したがって、キャッシュ アイテムへの要求にセキュリティ記述子フィールドが含まれる場合は、その要求が検索コネクタ フレームワークで無視されます。

外部コンテンツ タイプ メソッド

メタデータ モデルで、識別子に基づいて項目のセキュリティ記述子を返すメソッドが定義されている場合は、次の例に示すように、 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 ユーザーにマッピングできる場合、前の 2 つのコード例に示された方法を使用して、アイテム レベル セキュリティを実現できます。 これを正常に動作するには、外部システムのユーザーを Windows ユーザーに内部的に変換し、URL ごとに Windows セキュリティ記述子を返すメソッドが、外部システムで公開されている Web サービスまたは Windows Communication Foundation (WCF) サービスに含まれる必要があります。 次の例は、このメソッドのコーディング方法を示しています。

/// 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;
}

関連項目