コードでのアクセスの確認

注意

エンティティとテーブルの違いがわかりませんか? Microsoft Dataverse で「開発者: 用語を理解する」を参照してください。

セキュリティの概念について心配する必要がないのは、システム管理者セキュリティ ロールを使用してユーザーが実行することが期待されるコードを記述しているときだけです。 このロールはかなり強力で編集できないため、ユーザーは何でもできるので安心です。 他のすべての場合、セキュリティがどのように適用されるかを考慮する必要があります。

  • クライアント アプリケーション を作成している場合、テーブルまたは特定のテーブル レコードに対するユーザーの権限を評価し、有効にするコマンドを制御する必要があります。 ユーザーがテーブルの作成を許可されていない場合は、アプリのユーザー インターフェイスを無効にして、そのタイプの新しいテーブルの作成を許可できます。 テーブルへの読み取りアクセス権がない場合、クライアント アプリケーションは、そのタイプのテーブルのリストの表示に関連するコンポーネントの非表示を選択できます。

  • 同期プラグイン を記述する場合、データ操作を試みて例外を破棄することはどうしてもできません。 同期プラグイン内で失敗した操作があると、データ トランザクション全体がロールバックされます。 ユーザーの権限に応じてオプションのプロセスの一部がある場合は、最初にユーザーの権限を確認する必要があります。

ユーザーが実行できる操作を検出するために適用できる戦略は 2 つあります。

  • 個々のテーブル レコードをテストする
  • ユーザーのセキュリティ権限を確認してください

これらの戦略について以下に詳しく説明します。

個々のテーブル レコードをテストする

特定のテーブル レコードに対するユーザーの操作は、通常、クエリから始まります。 ユーザーがそのテーブルのレコードにアクセスできない場合、クエリは単にレコードを返さず、新しいレコードを作成する以外にユーザーが試行できることはありません。 ユーザーが新しいレコードを作成できるかどうかをテストするには、他の戦略 (上記) を使用してユーザーのセキュリティ特権を確認する必要があります。

ただし、ユーザーがクエリを使用してテーブル レコードの取得に成功した場合は、RetrievePrincipalAccess メッセージを使用してテーブル インスタンスをテストできます。

次のメソッドでは SDK RetrievePrincipalAccessRequest クラスを使用して、AccessRights 列挙内で定義されたアクセス権のセットを取得できるようにします。

/// <summary>
/// Gets which access rights a user has for a specific record.
/// </summary>
/// <param name="svc">The IOrganizationService instance to use.</param>
/// <param name="user">The user to check</param>
/// <param name="entity">A reference to the entity to check.</param>
/// <returns>The access rights the user can perform.</returns>

static AccessRights GetAccessRights(IOrganizationService svc, EntityReference
user, EntityReference entity) {

  try
  {
    var accessRightsRequest = new RetrievePrincipalAccessRequest() 
        { Principal = user, Target = entity };

    return ((RetrievePrincipalAccessResponse)svc.Execute(accessRightsRequest)).AccessRights;
  }
  catch (Exception)
  {
    throw;
  }
}

Web API の場合は、RetrievePrincipalAccess 関数と AccessRights EnumType を使用します。

このメソッドによって返される値を使用すると、Enum.HasFlag メソッド で、ユーザーがテーブルで特定の操作を実行するためのアクセス権を所有している場合にブール値を返すことができます。 次のコード スニペットは、上記の GetAccessRights() メソッドを使用し、AppendToAccess メンバーを使用して、ユーザーが特定のアカウント レコードにレコードを追加するためのアクセス権を持っているかどうかをテストする方法を示しています。

var whoIAm = (WhoAmIResponse)svc.Execute(new WhoAmIRequest());

var me = new EntityReference("systemuser", whoIAm.UserId);

// TODO Substitute a valid accountid GUID here.
var exampleAccount = (Account)svc.Retrieve("account",
    new Guid("4e9f3434-20e5-e811-a975-000d3af49bf8"), new ColumnSet("accountid"));

var accessRights = GetAccessRights(svc, me, exampleAccount.ToEntityReference());

var canAppendTo = accessRights.HasFlag(AccessRights.AppendToAccess);

テーブル レコードにアクセスすると、このメソッドを使用して、そのレコードに適用されるすべての操作をテストできます。 ただし、新しいレコードや特定のテーブルにバインドされていないその他の特権の作成など、他の操作に適用される機能は含まれていません。

レコードにアクセスできるプリンシパルを取得する

一部のデータ操作では、別のユーザーがレコードにアクセスできる必要があります。 特定のユーザーまたはチームが 1 つしかない場合は、RetrievePrincipalAccess メッセージ (RetrievePrincipalAccess関数、RetrievePrincipalAccessRequest クラス) を使用して他のユーザーをテストできます。

RetrieveSharedPrincipalsAndAccess メッセージ (RetrieveSharedPrincipalsAndAccess 関数、RetrieveSharedPrincipalsAndAccessRequest クラス) を使用して、アクセス権を持つすべてのユーザーとチームのリストと、レコードにおけるそれらのアクセス権に関する詳細を取得します。

ユーザーのセキュリティ権限を確認する

新しいテーブル レコードを作成できるかどうかなど、テストする特定のテーブル レコードがない場合は、ユーザーのセキュリティ権限の確認する必要があります。 これらの権限は、権限テーブル に保存されます。

Dataverse データベースには、約 1,000 の個別の特権があり、その数は、テーブルまたはカスタム アクションがシステムに追加される度に増加します。 次の FetchXML クエリを実行することにより、環境で使用可能な特権のリストを取得できます。

<fetch version='1.0' distinct='true' no-lock='true' >
  <entity name='privilege' >
    <attribute name='name' />
  </entity>
</fetch>

ヒント

XrmToolBox FetchXML ビルダーは、FetchXML クエリを作成およびテストするのに役立つツールです。

特権がテーブルに適用される場合、name 属性の値は、次の名前付け規則のパターンに従います: "prv+Verb+Table SchemaName"。 動詞は AppendAppendToAssignCreateDeleteShareWrite のいずれかです。

テーブルの特権に加えて、テーブルに関連付けられていない他の特別な特権の数は 100 未満です。 次のクエリを使用して、これらを取得できます。

<fetch version='1.0' distinct='true' no-lock='true' >

<entity name='privilege' >
  <attribute name='name' />
  <filter>
    <condition attribute='name' operator='not-begin-with' value='prvAppend' />
    <condition attribute='name' operator='not-begin-with' value='prvAssign' />
    <condition attribute='name' operator='not-begin-with' value='prvCreate' />
    <condition attribute='name' operator='not-begin-with' value='prvDelete' />
    <condition attribute='name' operator='not-begin-with' value='prvRead' />
    <condition attribute='name' operator='not-begin-with' value='prvShare' />
    <condition attribute='name' operator='not-begin-with' value='prvWrite' />
  </filter>
</entity>

</fetch>

これらのメッセージを使用して、特権 ID または名前で特権を取得します。 これには、ユーザーがチームから与えられる可能性のある特権が含まれます。

メッセージ Web API 関数
SDK 要求クラス
RetrieveUserPrivilegeByPrivilegeId RetrieveUserPrivilegeByPrivilegeId Function
RetrieveUserPrivilegeByPrivilegeIdRequest Class
RetrieveUserPrivilegeByPrivilegeName RetrieveUserPrivilegeByPrivilegeName Function
RetrieveUserPrivilegeByPrivilegeNameRequest Class
RetrieveUserSetOfPrivilegesByIds RetrieveUserSetOfPrivilegesByIds Function
RetrieveUserSetOfPrivilegesByNames RetrieveUserSetOfPrivilegesByNames Function

例: ユーザーが特権を持っているかどうかを確認する

次の例は、RetrieveUserPrivilegeByPrivilegeName メッセージの使用を示します。

この例では、systemuserid が 00000000-0000-0000-0000-000000000001 のユーザーが prvReadAuditSummary 権限を持っているかどうかをテストします。 RetrieveUserPrivilegeByPrivilegeNameResponse ComplexType.RolePrivileges コレクションにデータが含まれているので、ユーザーには権限があることになります。

要求

GET [Organization Uri]/api/data/v9.2/systemusers(00000000-0000-0000-0000-000000000001)/Microsoft.Dynamics.CRM.RetrieveUserPrivilegeByPrivilegeName(PrivilegeName='prvReadAuditSummary') HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Prefer: odata.include-annotations="*"

応答

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
Preference-Applied: odata.include-annotations="*"

{
    "@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.RetrieveUserPrivilegeByPrivilegeNameResponse",
    "RolePrivileges": [
        {
            "Depth": "Global",
            "PrivilegeId": "c2cbe3db-62c8-4661-9ac5-7691c83242f5",
            "BusinessUnitId": "38e0dbe4-131b-e111-ba7e-78e7d1620f5e",
            "PrivilegeName": "prvReadAuditSummary"
        }
    ]
}

詳細情報:

セキュリティ ロール用の特権を取得する

セキュリティ ロール別に特権を取得できます。 以下は、これがどのように行われるかを示す Web API 例です。

要求

GET [Organization URI]/api/data/v9.0/roles(<role ID>)/roleprivileges_association?$select=name&$orderby=privilegeid 

関連項目

プラグイン

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。