この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

with sharingwithout sharing、および inherited sharing キーワードの使用

クラスで with sharing または without sharing キーワードを使用して、共有ルールを適用するかどうかを指定します。クラスで inherited sharing キーワードを使用して、そのコール元のクラスの共有モードでクラスを実行します。

With Sharing

現在のユーザーの共有ルールを強制実行するには、クラスの宣言時に with sharing キーワードを使用します。このキーワードを明示的に設定すると、現在のユーザーコンテキストで Apex コードが実行されます。executeAnonymous コールで実行された Apex コードと Connect in Apex は、常に現在のユーザーの共有ルールを使用して実行されます。executeAnonymous の詳細は、「匿名ブロック」を参照してください。

現在のユーザーに適用されている共有ルールを強制実行するには、クラスの宣言時に with sharing キーワードを使用します。次に例を示します。

1public with sharing class sharingClass {
2
3   // Code here
4
5}

Without Sharing

現在のユーザーに適用されている共有ルールを強制実行されないようにするには、クラスの宣言時に without sharing キーワードを使用します。たとえば、クラスが with sharing を使用して宣言された別のクラスからコールされた場合、共有ルールの強制実行を明示的にオフにできます。

1public without sharing class noSharing {
2
3   // Code here
4
5}

Inherited Sharing

コール元のクラスの共有ルールを強制実行するには、クラスの宣言時に inherited sharing キーワードを使用します。inherited sharing の使用は、実行時に共有モードを決定し、with sharing または without sharing モードで実行可能な Apex クラスを設計する高度な手法です。

実行時に共有モードが決まるため、Apex コードが with sharingwithout sharing の両方のモードで安全に実行されるように細心の注意を払う必要があります。

警告

他の適切なセキュリティチェックと共に inherited sharing を使用することで、AppExchange セキュリティレビューを簡単に渡すことができ、予期しない方法や安全でない方法での特権 Apex コードの使用を防止できます。inherited sharing を指定した Apex クラスは、Apex トランザクションへのエントリポイントとして使用される場合 (フローなど)、または以下のものとして使用される場合には、with sharing として実行されます。
  • Aura コンポーネントコントローラー
  • Visualforce コントローラー
  • Apex REST サービス

inherited sharing のある Apex クラスと省略された共有宣言のある Apex クラスには、明確な違いがあります。クラスが Apex トランザクションの開始点として使用されている場合、省略された共有宣言は without sharing として実行されます。一方、inherited sharing ではデフォルトで確実に with sharing として実行されます。inherited sharing として宣言されたクラスが without sharing として実行されるのは、すでに確立されている without sharing コンテキストから明示的にコールされた場合のみです。

この例では、inherited sharing のある Apex クラスとその Apex コードの Visualforce 呼び出しを宣言します。inherited sharing 宣言により、実行ユーザーが共有アクセス権を持つ取引先責任者のみが表示されます。この宣言が省略されている場合、安全でないデフォルトの動作により、ユーザーが参照権限を持たない取引先責任者も表示されます。
1public inherited sharing class InheritedSharingClass {
2    public List<Contact> getAllTheSecrets() {
3        return [SELECT Name FROM Contact];
4    }
5}
1<apex:page controller="InheritedSharingClass">
2    <apex:repeat value="{!allTheSecrets}" var="record">
3        {!record.Name}
4    </apex:repeat>
5</apex:page>

実装の詳細

  • メソッドがコールされるクラスの共有設定ではなく、メソッドが定義されているクラスの共有設定が適用されます。たとえば、with sharing として宣言されたクラス内に定義されているメソッドが、without sharing として宣言されたクラスでコールされる場合、そのメソッドの実行では共有ルールが適用されます。
  • クラスが with sharing または without sharing として明示的に宣言されていない場合、現在の共有ルールが有効となります。そのため、クラスが別のクラスから共有ルールを取得する場合を除き、共有ルールは強制実行されません。たとえば、共有が強制実行されている別のクラスからクラスがコールされた場合、コールされたクラスにも共有が強制実行されます。
  • 内部クラスと外部クラスは、どちらも with sharing として宣言できます。内部クラスはそのコンテナクラスから共有設定を継承しません。それ以外の場合、共有設定は、初期化コード、コンストラクター、メソッドなどクラスに含まれているすべてのコードに適用されます。
  • クラスが別のクラスを拡張または実装している場合、親クラスから共有設定が継承されます。
  • Apex トリガーには明示的な共有宣言を含めることはできず、without sharing として実行できません。

ベストプラクティス

明示的な共有宣言のない Apex は、デフォルトでは安全ではありません。常にクラスの共有宣言を指定することを強くお勧めします。

共有モードに関係なく、オブジェクトレベルアクセスと項目レベルセキュリティは Apex で適用されません。オブジェクトレベルアクセスと項目レベルセキュリティは、SOQL クエリまたはコードで適用する必要があります。たとえば、with sharing メカニズムでは、レポートおよびダッシュボードを参照するためのユーザーのアクセス権は適用されません。コードで実行ユーザーの CRUD (作成、参照、更新、削除) および項目レベルセキュリティを明示的に適用する必要があります。「オブジェクト権限と項目権限の適用」を参照してください。

共有モード 使用するケース
with sharing 使用事例で必要ない限り、このモードをデフォルトとして使用します。
without sharing

このモードを使用する場合��注意が必要です。共有モデルによって通常は非表示となる機密データが不注意で公開されないようにしてください。この共有メカニズムは、目的の昇格された共有権限を現在のユーザーに付与する場合に最適です。

たとえば、コミュニティユーザーが通常ではアクセスできないレコードを参照できるようにする場合に without sharing を使用します。

inherited sharing このモードは、さまざまな共有モードのある使用事例 (より安全な with sharing モードがデフォルト) に対応できる柔軟性が必要なサービスクラスで使用します。