概要
SalesforceのApexには、ユーザーのアクセス権に基づいてレコードへのアクセスを制御するためのキーワードが提供されています。これらのキーワードは”with sharing”、”without sharing”、および”inherited sharing”です。
- with sharing:
- このキーワードを使用すると、ユーザーがアクセス権を持つレコードのみにアクセスできます。ユーザーがアクセス権を持たないレコードは表示されません。
- without sharing:
- このキーワードを使用すると、ユーザーのアクセス権を無視して、すべてのレコードにアクセスできます。特定の管理タスクや特定のシステム操作のために使われることが多いです。また、アクセス修飾子の
sharing
キーワードが指定されていない場合、デフォルトでwithout sharing
として動作します。
- このキーワードを使用すると、ユーザーのアクセス権を無視して、すべてのレコードにアクセスできます。特定の管理タスクや特定のシステム操作のために使われることが多いです。また、アクセス修飾子の
- inherited sharing:
- このキーワードを使用すると、呼び出し元の
sharing
キーワードの設定をそのまま引き継ぎます。たとえば、元々with sharing
の設定で呼び出されたメソッドやクラスからさらに別のメソッドやクラスが呼び出された場合、後者は前者のwith sharing
設定を継承します。
- このキーワードを使用すると、呼び出し元の
使い方
with sharing
このキーワードを使用すると、ユーザーがアクセス権を持つレコードのみにアクセスできます。
public with sharing class MyWithSharingClass {
public List<Account> getAccessibleAccounts() {
return [SELECT Id, Name FROM Account];
}
}
このクラスは、現在のユーザーがアクセス権を持つAccountレコードのみを取得します。
with sharing
このキーワードを使用すると、ユーザーのアクセス権を無視して、すべてのレコードにアクセスできます。
public without sharing class MyWithoutSharingClass {
public List<Account> getAllAccounts() {
return [SELECT Id, Name FROM Account];
}
}
このクラスは、アクセス権に関係なく、すべてのAccountレコードを取得します。
with sharing
このキーワードを使用すると、呼び出し元のアクセス制御の設定を引き継ぎます。
public inherited sharing class MyInheritedSharingClass {
public List<Account> getAccountsBasedOnCaller() {
return [SELECT Id, Name FROM Account];
}
}
このクラスは、呼び出し元のアクセス制御設定に基づいてAccountレコードを取得します。もし呼び出し元がwith sharingであれば、アクセス権を持つレコードのみを取得し、without sharingであればすべてのレコードを取得します。
実装の詳細
- メソッドの共有設定の適用:
- メソッドがどのクラスからコールされるかに関係なく、メソッドが定義されているクラスの共有設定が適用されます。例えば、
with sharing
で定義されたメソッドが、without sharing
のクラスからコールされた場合でも、そのメソッドはwith sharing
の設定で実行されます。
- メソッドがどのクラスからコールされるかに関係なく、メソッドが定義されているクラスの共有設定が適用されます。例えば、
- 明示的な共有宣言のないクラス:
- クラスに
with sharing
やwithout sharing
の明示的な宣言がない場合、そのクラスは実行時の共有ルールに従います。つまり、クラス自体に特定の共有設定がないため、実行される際には、そのクラスを呼び出している他のコード(親クラスや外部クラスなど)の共有ルールに依存します。例えば、with sharing
で宣言されたクラスからこのようなクラスが呼び出される場合、実行時にはwith sharing
のルールが適用されます。
- クラスに
- 内部クラスと外部クラスの共有宣言:
- 内部クラスは外部クラスの共有設定を継承しません。それぞれ独立して
with sharing
またはwithout sharing
と宣言できます。
- 内部クラスは外部クラスの共有設定を継承しません。それぞれ独立して
- 内部クラスの共有設定の継承:
- 内部クラスは、外部クラスから共有設定を継承しません。これは、内部クラスが独自の共有設定を持つ必要があることを意味します。
public with sharing class ExternalClass {
// 外部クラスのコード
class InternalClass {
// この内部クラスは、外部クラスの`with sharing`設定を継承しません。
// 明示的にsharingキーワードを設定していない場合、デフォルトでwithout sharingとして動作します。
}
}
- Apex トリガーの共有宣言:
- Apex トリガーは、明示的な共有宣言を持つことができません。そのため、トリガーは常に
without sharing
の設定で実行されます。
- Apex トリガーは、明示的な共有宣言を持つことができません。そのため、トリガーは常に
ベストプラクティス
- 安全性の確保: Apexクラスを作成する際、共有設定を明示的に指定しない場合、安全性が確保されない可能性があります。したがって、常に共有設定を明示的に指定することが推奨されます。
- オブジェクトおよび項目のアクセス制御: 共有設定だけでは、オブジェクトや項目のアクセス制御は行えません。これらの制御は、別途設定が必要です。
- 共有モードの適切な利用:
- with sharing: 特に理由がない限り、この設定をデフォルトとして利用することが推奨されます。
- without sharing: この設定を利用する際は、慎重に操作する必要があります。誤って機密情報を公開してしまうリスクがありますが、特定のユーザーに情報を提供する場合に有効です。
- inherited sharing: さまざまな状況に対応するための設定です。基本的には、
with sharing
を基準として利用することが望ましいです。
まとめ
Apexにおけるwith sharing、without sharing、およびinherited sharingは、ユーザーのアクセス権に基づいてレコードへのアクセスを制御するためのキーワードです。これにより、データのセキュリティとアクセス制御を柔軟に実現することができます。
コメント