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 クラスを設計する高度な手法です。
- Aura コンポーネントコントローラー
- Visualforce コントローラー
- Apex REST サービス
inherited sharing のある Apex クラスと省略された共有宣言のある Apex クラスには、明確な違いがあります。クラスが Apex トランザクションの開始点として使用されている場合、省略された共有宣言は without sharing として実行されます。一方、inherited sharing ではデフォルトで確実に with sharing として実行されます。inherited sharing として宣言されたクラスが without sharing として実行されるのは、すでに確立されている without 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 モードがデフォルト) に対応できる柔軟性が必要なサービスクラスで使用します。 |