オブジェクトレベルおよび項目レベルのアクセス設定のスキップ
標準オブジェクトとカスタムオブジェクトに対して、組織の CRUD (作成、参照、更新、削除) 設定と FLS (項目レベルセキュリティ) 設定を適用するようにソリューションを設計します。
Salesforce Platform では、プロファイルと権限セットに対して CRUD アクセスと FLS を設定できます。CRUD 設定は、ユーザーがアクセス可能なオブジェクトを決定します。FLS は、ユーザーがアクセス可能なオブジェクト項目を決定します。標準オブジェクトとカスタムオブジェクト、および個々の項目へのアクセスを制限するには、CRUD と FLS を使用します。
顧客は、自分が組織で行った設定にソリューションが違反しないことを期待しています。標準オブジェクトとカスタムオブジェクトに対して、組織の CRUD 設定と FLS 設定を適用するようにソリューションを設計します。また、ユーザーのアクセスが制限される状況をソリューションが適切に処理することを確認します。
使用事例によっては��CRUD と FLS のスキップが許容されることがあります。たとえば、次のような場合です。
- データを直接公開しない積み上げ集計、または集計を作成する。
- ログやシステムメタデータなどのカスタムオブジェクトまたは項目を変更して、ユーザーが CRUD または FLS 経由で直接アクセスできないようにする。
- 管理者以外のユーザーはアクセスできないメソッドである高特権メソッドからオブジェクトにアクセスする。
- ソリューションがコミュニティまたはサイトの場合は、基盤となるオブジェクトへのゲストユーザーのアクセスを拒否する。
- 特注のセキュリティポリシーを使用して、名前空間に属しているカスタムオブジェクトにアクセスする。この場合は、AppExchange セキュリティレビュー申請の一環として、ポリシーを文書化します。
CRUD および FLS の適用についての詳細は、Trailhead の「Secure Server-Side Development module (セキュアなサーバーサイド開発モジュール)」を確認してください。コードで CRUD/FLS 違反を検出するには、Salesforce Code Analyzer の Salesforce Graph Engine などのコードスキャナーの使用を検討してください。
Apex の例
次の Apex コードの場合、データ操作言語 (DML) のステートメント insert account は、Account オブジェクトの作成アクセス権限がユーザーにあるかどうかを確認せずに実行されます。このコードは、組織のアクセス設定を適用しません。
1public static Account createIndividualModalData(String name, String email, String mobile) {
2 RecordType recordType = [Select Id from RecordType where DeveloperName = 'IndustriesIndividual' and SobjectType = Account'];
3 Account account = new Account();
4 account.Name = name;
5
6 if(recordType != null) account.RecordTypeId = recordType.id;
7 insert account;
8 ...
9}この Apex コードは、組織のアクセス設定を適用するため、安全性が高くなっています。insert account DML ステートメントが実行される前に isCreatable() メソッドをコールします。isCreatable() が true を返した場合、ユーザーは、Account オブジェクトの作成アクセス権限を所有しており、insert account ステートメントが実行されます。それ以外の場合は、アクセス権がないというエラーが報告されます。
1public static Account createIndividualModalData(String name, String email, String mobile) {
2 RecordType recordType = [Select Id from RecordType where DeveloperName = 'IndustriesIndividual' and SobjectType = 'Account'];
3 Account account = new Account();
4 account.Name = name;
5
6 if(recordType != null) account.RecordTypeId = recordType.id;
7
8 if (Schema.sObjectType.Account.isCreateable()) {
9 insert account;
10 } else {
11 ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Insufficient Access'));
12 }
13 ...
14}