Apex クラスの保護
デフォルトでは、Apex はシステムモードで実行されます。つまり、非常に上位の権限で実行され、あたかもユーザがほとんどの権限を持っていてすべての項目レベルおよびオブジェクトレベルのアクセス権が付与されているように動作します。これらのセキュリティレイヤが Salesforce UI のように適用されないため、適用するためのコードを記述する必要があります。そうしないと、通常は Salesforce UI ではユーザに表示されない機密データがコンポーネントによって公開されてしまう可能性があります。
Salesforce のレコードを処理する場合は、共有ルール、CRUD、および項目レベルセキュリティをユーザに代わって扱ってくれる Lightning Data Service の使用をお勧めします。「データガイドライン」を参照してください。
認証済みユーザまたはゲストユーザは、ユーザのプロファイルまたは割り当てられた権限セットで Apex クラスへのアクセスが許可されている場合にのみ、@AuraEnabled
Apex メソッドにアクセスできます。
Apex クラスへのユーザプロファイルまたは権限セットのアクセス権の設定についての詳細は、『Apex 開発者ガイド』の「クラスのセキュリティ」を参照してください。
クラスを宣言するときには、with sharing
を指定して、コンポーネントが Apex コントローラを使用するときに共有ルールを適用することをお勧めします。
with sharing
または without sharing
を明示的に設定しない、あるいは inherited sharing
を使用して定義された @AuraEnabled
Apex クラスは、デフォルトまたは暗黙的な値として with sharing
を使用します。ただし、with sharing
または without sharing
のどちらも明示的に指定されていない Apex クラスでは、Apex クラスが実行されているコンテキストから値が継承されます。したがって、このいずれかのキーワードを設定したクラスによって、明示的な共有動作を指定していないクラスが呼び出された場合、そのクラスは呼び出し元のクラスの共有動作を使用して動作します。クラスで共有ルールが適用されるようにするには、with sharing
を設定します。
with sharing
キーワードを使用すると、レコードレベルのセキュリティが適用されます。オブジェクトレベルおよび項目レベルのセキュリティは適用されません。オブジェクトレベルおよび項目レベルのセキュリティは、Apex クラスで手動で別々に適用する必要があります。
Apex コード内でオブジェクトレベルおよび項目レベルの権限を適用するには、いくつかの代替方法があります。
WITH SECURITY_ENFORCED
を使用した最も簡単な適用オブジェクトレベルおよび項目レベルの権限を適用するには、Apex コード内の
SOQL SELECT
クエリ (サブクエリとクロスオブジェクトリレーションを含む) でWITH SECURITY_ENFORCED
句を使用します。WITH SECURITY_ENFORCED
句は、セキュアなコードの開発経験が少ししかない場合や、権限エラーのグレースフルデグラデーションがアプリケーションで不要な場合に最適です。次の例では、セキュアでないメソッド
get_UNSAFE_Expenses()
を含むカスタム Expense オブジェクトの項目が照会されます。このクラスは使用しないでください。次の例では、セキュアなメソッド
getExpenses()
が使用されます。このメソッドは、WITH SECURITY_ENFORCED
句を使用して、オブジェクトレベルの権限と項目レベルの権限を適用します。このクラスはUnsafeExpenseController
の代わりに使用します。詳細は、『Apex 開発者ガイド』を参照してください。
stripInaccessible()
を使用したグレースフルデグラデーション権限エラーのグレースフルデグラデーションを可能にするには、
stripInaccessible()
メソッドを使用して項目レベルおよびオブジェクトレベルのデータ保護を適用します。このメソッドではクエリおよびサブクエリの結果からユーザがアクセスできない項目およびリレーション項目を除外します。必要に応じて、項目が除外されたかどうかを検出し、カスタムエラーメッセージを含むAuraHandledException
を発生させることができます。このメソッドを使用すると、DML 操作の前にアクセス不可の sObject 項目を削除して例外を回避したり、信頼できないソースからデシリアライズされた sObject をサニタイズしたりすることもできます。
次の例では、
WITH SECURITY_ENFORCED
SOQL 句の代わりにstripInaccessible()
を使用するようにExpenseController
が更新されます。結果は同じになりますが、stripInaccessible()
では、WITH SECURITY_ENFORCED
の使用時にアクセス違反が発生した場合、失敗する代わりに、グレースフルデグラデーションを行うことができます。詳細や例については、『Apex 開発者ガイド』を参照してください。
DescribeSObjectResult
メソッドとDescribeFieldResult
メソッドを使用した従来のコードWITH SECURITY_ENFORCED
句とstripInaccessible()
メソッドが使用できるようになるまでは、オブジェクトと項目の権限を適用する唯一の方法は、Schema.DescribeSObjectResult
メソッドとSchema.DescribeFieldResult
メソッドをコールしてユーザのアクセス権限を確認することでした。そして、ユーザに必要な権限がある場合には特定の DML 操作またはクエリを実行します。たとえば、
Schema.DescribeSObjectResult
のisAccessible
、isCreateable
、またはisUpdateable
メソッドをコールすると、現在のユーザーがsObject
に対して、それぞれ参照アクセス権、作成アクセス権、または更新アクセス権を持っているかどうかを確認できます。同様に、Schema.DescribeFieldResult
が公開しているアクセス制御メソッドをコールすると、現在のユーザーが項目に対して参照アクセス権、作成アクセス権、または更新アクセス権を持っているかどうかを確認できます。次の例では、Describe Result メソッドが使用されています。この方法では、定型のコード行がさらに多く必要になるため、代わりに
WITH SECURITY_ENFORCED
句またはstripInaccessible()
メソッドを使用することをお勧めします。
関連トピック
- Apex 開発者ガイド: 共有ルールの適用
- Apex 開発者ガイド: オブジェクト権限と項目権限の適用
- Apex 開発者ガイド: with sharing、without sharing、および inherited sharing キーワードの使用
- Secure Coding Guide (セキュアなコーディングガイド): Lightning Security (Lightning セキュリティ)