0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Apexにおけるデータアクセス時のセキュリティ機能

Posted at

SalesforceのApexでデータアクセスのセキュリティを考慮するとき、以下の4つの機能を理解することが重要です。

  1. アクセスレベルパラメータ(Access Level Parameters)
  2. WITH SECURITY_ENFORCED
  3. Security.stripInaccessible()
  4. Apex Describe Information

それぞれの役割や違い、実装例を整理しました。


1. アクセスレベルパラメータ(Access Level Parameters)

概要

  • SOQLクエリやDML操作でオブジェクトやフィールドレベルのアクセス制御を行うためのパラメータ
  • Apexコードが「ユーザーの権限を考慮するか」を決めるのに使う。
  • 主にDML操作(insert, update, delete)で使われる

使えるアクセスレベル

レベル 説明
USER_MODE ユーザーの権限を考慮する(プロファイルや権限セットを適用)
SYSTEM_MODE 管理者権限で実行(アクセス制限を無視)

実装例

// USER_MODEを使用(ユーザーのアクセス権を考慮)
Database.SaveResult result = Database.insert(myRecord, AccessLevel.USER_MODE);

// SYSTEM_MODEを使用(管理者権限で実行)
Database.SaveResult result2 = Database.insert(myRecord, AccessLevel.SYSTEM_MODE);

どんなときに使う?

管理者のように実行する場合(SYSTEM_MODE)
標準のアクセス制御を適用したい場合(USER_MODE)

⚠️ 注意点

  • DML 操作で使うものなので、SOQLクエリには影響しない。
  • USER_MODE にすると、ユーザーがアクセスできないオブジェクトやフィールドには書き込めない

2. WITH SECURITY_ENFORCED

概要

  • SOQLクエリ実行時に、ユーザーがアクセスできないフィールドを自動的に除外する
  • SOQLのクエリに直接組み込めるので簡単に使える
  • フィールドレベルセキュリティ(FLS)を考慮する。

実装例

List<Account> accounts = [SELECT Id, Name, Industry FROM Account WITH SECURITY_ENFORCED];

ユーザーが「Industry」フィールドにアクセス権を持っていない場合、クエリは失敗(例外発生)する。

どんなときに使う?

SOQLクエリ時に、アクセス権を考慮したいとき
シンプルなコードでセキュリティを担保したいとき

⚠️ 注意点

  • アクセスできないフィールドが含まれていると 例外(Exception)が発生する
  • 一部のフィールドだけ取得したいときは Security.stripInaccessible() の方が便利

3. Security.stripInaccessible()

概要

  • アクセスできないフィールドを自動的に除外してくれる(クエリもDML操作も対象)
  • WITH SECURITY_ENFORCED との違い → クエリが失敗せず、アクセス可能なデータのみ取得できる
  • データの作成・更新時にも使えるので、汎用性が高い

実装例

// クエリ実行(ユーザーがアクセスできないフィールドを自動的に除外)
SObjectAccessDecision decision = Security.stripInaccessible(AccessType.READABLE, [SELECT Id, Name, Industry FROM Account]);
List<Account> safeAccounts = (List<Account>)decision.getRecords();

アクセス権のない「Industry」フィールドが自動的に除外されるため、例外は発生しない。

データ更新時の使用例

Account acc = new Account(Id = '001xxxxxxx', Industry = 'Technology'); // Industryが制限されている可能性あり
SObject sanitizedAccount = Security.stripInaccessible(AccessType.UPDATABLE, acc);
update sanitizedAccount;

Industry フィールドが更新不可なら、自動的に除外されて安全にupdateできる

どんなときに使う?

クエリ時にアクセスできないフィールドを自動的に取り除きたいとき
DML操作時に、アクセスできないフィールドを除外してエラーを防ぎたいとき

⚠️ 注意点

  • WITH SECURITY_ENFORCED とは違い、クエリの失敗はしないが、アクセスできないフィールドは結果から消える
  • クエリだけでなく、DML操作でも使えるのがメリット。

4. Apex Describe Information

概要

  • オブジェクトやフィールドのメタデータを動的に取得できる
  • フィールドレベルセキュリティ(FLS)やオブジェクトレベルセキュリティ(CRUD)のチェックをカスタム処理で行うときに使う
  • 「ユーザーがこのフィールドを読めるか・書けるか?」を事前にチェックできる

実装例

// ユーザーが Account オブジェクトに対する read 権限を持っているか確認
if (Schema.sObjectType.Account.isAccessible()) {
    List<Account> accounts = [SELECT Id, Name FROM Account];
}

// ユーザーが Account の Industry フィールドを編集できるか確認
if (Schema.sObjectType.Account.fields.Industry.isUpdateable()) {
    Account acc = new Account(Id = '001xxxxxxx', Industry = 'Technology');
    update acc;
}

どんなときに使う?

カスタムのロジックでアクセス制御をしたいとき
CRUDやFLSチェックをコードで実装したいとき

⚠️ 注意点

  • WITH SECURITY_ENFORCEDSecurity.stripInaccessible() の方が簡単なので、通常はそれを使う
  • 動的な権限チェックが必要な場合にのみ使う(例:カスタムUIでボタンを表示/非表示)

まとめ:どれを使えばいい?

機能 役割 使う場面 クエリ DML
Access Level Parameters DML時の権限制御 DML(insert, update, delete)でユーザー権限を適用
WITH SECURITY_ENFORCED クエリのセキュリティ適用 SOQLでFLSを適用し、アクセスできない場合はエラーにする
Security.stripInaccessible() クエリとDMLのフィールド制御 クエリ時にアクセスできないフィールドを除外 / DML時に変更不可のフィールドを削除
Apex Describe Information 権限チェック(CRUD/FLS) コード内で動的に権限チェックをする

どれを使うべき?

  • SOQLクエリWITH SECURITY_ENFORCED or Security.stripInaccessible()
  • DML操作Security.stripInaccessible() or Access Level Parameters (USER_MODE)
  • 動的に権限をチェックしたいApex Describe Information

適切に使い分けることで、安全でエラーの少ないApexコードを実装できます! 🚀

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?