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

概要

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であればすべてのレコードを取得します。

実装の詳細

  1. メソッドの共有設定の適用:
    • メソッドがどのクラスからコールされるかに関係なく、メソッドが定義されているクラスの共有設定が適用されます。例えば、with sharingで定義されたメソッドが、without sharingのクラスからコールされた場合でも、そのメソッドはwith sharingの設定で実行されます。
  2. 明示的な共有宣言のないクラス:
    • クラスにwith sharingwithout sharingの明示的な宣言がない場合、そのクラスは実行時の共有ルールに従います。つまり、クラス自体に特定の共有設定がないため、実行される際には、そのクラスを呼び出している他のコード(親クラスや外部クラスなど)の共有ルールに依存します。例えば、with sharingで宣言されたクラスからこのようなクラスが呼び出される場合、実行時にはwith sharingのルールが適用されます。
  3. 内部クラスと外部クラスの共有宣言:
    • 内部クラスは外部クラスの共有設定を継承しません。それぞれ独立してwith sharingまたはwithout sharingと宣言できます。
  4. 内部クラスの共有設定の継承:
    • 内部クラスは、外部クラスから共有設定を継承しません。これは、内部クラスが独自の共有設定を持つ必要があることを意味します。
public with sharing class ExternalClass {
    // 外部クラスのコード
    class InternalClass {
        // この内部クラスは、外部クラスの`with sharing`設定を継承しません。
        // 明示的にsharingキーワードを設定していない場合、デフォルトでwithout sharingとして動作します。
    }
}
  1. Apex トリガーの共有宣言:
    • Apex トリガーは、明示的な共有宣言を持つことができません。そのため、トリガーは常にwithout sharingの設定で実行されます。

ベストプラクティス

  • 安全性の確保: Apexクラスを作成する際、共有設定を明示的に指定しない場合、安全性が確保されない可能性があります。したがって、常に共有設定を明示的に指定することが推奨されます。
  • オブジェクトおよび項目のアクセス制御: 共有設定だけでは、オブジェクトや項目のアクセス制御は行えません。これらの制御は、別途設定が必要です。
  • 共有モードの適切な利用:
    • with sharing: 特に理由がない限り、この設定をデフォルトとして利用することが推奨されます。
    • without sharing: この設定を利用する際は、慎重に操作する必要があります。誤って機密情報を公開してしまうリスクがありますが、特定のユーザーに情報を提供する場合に有効です。
    • inherited sharing: さまざまな状況に対応するための設定です。基本的には、with sharingを基準として利用することが望ましいです。

まとめ

Apexにおけるwith sharing、without sharing、およびinherited sharingは、ユーザーのアクセス権に基づいてレコードへのアクセスを制御するためのキーワードです。これにより、データのセキュリティとアクセス制御を柔軟に実現することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

雇われのシステムエンジニアです。
普段は車載ECUのセキュリティー分野に従事しております。

■保有資格
Salesforce 認定 アドミニストレーター
Salesforce 認定 Platform アプリケーションビルダー
Salesforce 認定 Platform デベロッパー

コメント

コメントする

目次