こんにちは、管理人の@Salesforce.Zです。
普段、 Apex はシステムコンテキストで実行されます。つまり、コード実行時に、現在のユーザの権限、項目レベルセキュリティ、および共有ルールは考慮されません。
もちろん、特例があります。 それは、コンソール匿名(executeAnonymous )コールおよび Chatter in Apex と共に実行される Apex コードです。 コンソール匿名 executeAnonymous は常に、現在のユーザのフル権限を用いて実行されます 。
Contents
ちょい説明
【Apex】with sharingキーワードとwithout sharingキーワード
クラスで with sharing または without sharing キーワードを使用して、共有ルールを適用するかどうかを指定できます。
with sharing例(ユーザモードで実行)
1 2 3 4 5 |
public with sharing class SharingClass { // Code here } |
without sharing例(システムモードで実行)
1 2 3 4 5 |
public without sharing class NoSharingClass { // Code here } |
トリガ (システムモードで実行)
1 2 3 |
trigger TriggerName on ObjectName (trigger_events) { //code_block } |
拡張説明(クラスの継承)
メソッドがコールされるクラスの共有設定ではなく、メソッドが定義されているクラスの共有設定が適用されます。たとえば、with sharing が宣言されたクラス内に定義されているメソッドが、without sharing が宣言されたクラスでコールされる場合、そのメソッドの実行では共有ルールが適用されます 。
下記の親クラスと外部子クラスのように、親クラスcallOtherClassMethodメソッドは
ユーザモードで実行されること。子クラスがシステムモードのクラスにもかかわらず。
1 2 3 4 5 6 7 8 9 |
/**with sharing 親クラス*/ public with sharing class sharingParentClass { public callOtherClassMethod(){ // 外部の子クラスをコール NoSharingChildClass.methodA(); } } |
1 2 3 4 5 6 7 8 9 |
/**without sharing 外部子クラス*/ public without sharing class NoSharingChildClass { public static List<sObject> methodA(){ return [SELECT Id, Name From sObject limit 9]; } } |
with sharing および without sharing キーワードに関する実装の詳細
公式サイトにも記載してあるがリンクが変更される可能性もあるため、ここに引用させていただきます。結構重要なので、使いこなしたら、すごい良いと思います。
with sharing、without sharing、および inherited sharing キーワードの使用1.メソッドがコールされるクラスの共有設定ではなく、メソッドが定義されているクラスの共有設定が適用されます。たとえば、with sharing
Salesforce公式ドキュメント(ヘルプ)
が宣言されたクラス内に定義されているメソッドが、without sharing
が宣言されたクラスでコールされる場合、そのメソッドの実行では共有ルールが適用されます。
2.with sharing も without sharing もクラスで宣言されていない場合、現在の共有ルールが有効となります。そのため、クラスが別のクラスから共有ルールを取得する場合を除き、共有ルールは強制実行されません。たとえば、共有が強制実行されている別のクラスからクラスがコールされた場合、コールされたクラスにも共有が強制実行されます。
3.内部クラスと外部クラスは、どちらも with sharing
として宣言できます。共有設定は、初期化コード、コンストラクタ、メソッドなどクラスに含まれているすべてのコードに適用されます。
4.内部クラスはそのコンテナクラスから共有設定を継承しません。
5.クラスが別のクラスを拡張または実装している場合、親クラスからこの設定が継承されます。
【Apex】オブジェクト権限と項目権限
ここから、APEXでCRUD操作をする前に関連する項目に対して、権限を確認し、
権限がある場合のみ、関連CRUD操作を行うようにする、きっと変なエラーにならないでしょう。システム正式運用時にたまに、予想外のエラーがシステム管理者に届き、
見ても想像がつかない。調査すると、権限のないユーザで、トリガや機能を発火して、発生したとか、業務上では、あり得ないだけど、業務をする人ではない場合、めっちゃくちゃのリレーションを結ぶし、変更するし、常識ではないデータも作る。こんなケースは少なくない、よって、予想外なエラーがきっとどこかで、発生するでしょう。普通はCRUDを実施するところにはtry catchブロックはもちろんん、Savepointや権限確認もやるべきかと思っています。
現在のユーザに sObject に対する参照、作成または更新のアクセス権があるかどうかをそれぞれ確認するには、Schema.DescribeSObjectResult の isAccessible, isCreateable メソッドまたは isUpdateable メソッドを呼び出すことにより 可能です。
APEXで更新する前に項目の更新権限確認例
1 2 3 4 |
//取引先責任者のメール項目を更新する前、項目レベルの更新権限を確認する if (Schema.sObjectType.Contact.fields.Email.isUpdateable()) { // Update contact phone number } |
APEXで作成する前に項目の作成権限確認例
1 2 3 4 |
//取引先責任者を作成する前に、メール項目の項目レベルの作成権限を確認する if (Schema.sObjectType.Contact.fields.Email.isCreateable()) { // Create new contact } |
APEXで参照する前に項目の参照権限確認例
1 2 3 4 |
// 取引先責任者のメール項目を参照する前に、項目レベルの参照権限を確認する if (Schema.sObjectType.Contact.fields.Email.isAccessible()) { Contact c = [SELECT Email FROM Contact WHERE Id= :Id]; } |
APEXで削除する前に オブジェクトレベルの削除権限確認例
1 2 3 4 |
//削除権限がある場合、削除操作を行う if (Schema.sObjectType.Contact.isDeletable()) { // Delete contact } |
実行パターンと実行権限まとめ

簡単説明
計9回検証しました。
#1~#9まではいずれもメインクラスがあり、中からDAOクラスをコール、DAOのクエリ結果を確認する方法です。
システム管理者列はシステム管理者で、データを用意する意味
前提条件は取引先の共有設定は
非公開
になっていること
#1検証
1 2 3 4 5 |
public with sharing class mainClass{ public void mainClass(){ System.debug('検索結果件数:' + mainDAO.getAccount().size()); } } |
1 2 3 4 5 6 7 8 9 |
public with sharing class mainDAO{ public static List<Account> getAccount(){ return [SELECT Id , Name FROM Account ] } } |
上記のmainClassをシステム管理者で、3件データを用意した上で
・システム管理者で、実行する結果が3件を見つかりました。
・別ユーザで、実行する結果が0件
#2~#9まで、同じようにメインクラスとDAOクラスで、with sharing とwithout sharingで組み合わせて、システム管理者と別ユーザで、クラスを実行し、見つかったデータ件数を検証する方法で、結果を表にまとめました。
この記事の上半部分に引用部分に対して、検証した結果。そして表にしたものです。
たいしたことではありませんが、やってみると印象が深い
終わりに
Apex実行するには本当にオブジェクトレベル、レコードレベル、項目レベルで考慮を厳密に行うと大変です。そんなリーダーも少ないはず。なんとか納期に間に合えば、もう立派と見られる時期です。
お客様がこの部分を業務上で、しっかりするので、そんなに合わないじゃないかと思います。お客様が仕事の真面目さで、ITがある程度、この部分をすこしさぼれるが、違う国のお客様だと、本当にでたらめなことをしあがってくれるのです。業務上ではありえないことをだれか、そのように動かす可能性が十分ある。
経理なのに、○○機能を動かすと、きっとエラーやろう
工事の人なのに、経理機能を動かすと、きっとエラーやろう
ただしいユーザで、動いてくれませんかといいたいけど、UATなのでそんな適切な方がなかなか来れなくて …💦
※本気でUATじゃないよね