【Apex Security and Sharing】在 Apex 中判断字段级别(FieldLevelSecurity)的权限(使用WITH SECURITY_ENFORCED关键词)
2023年10月21日
文章浏览:396
需求:Apex的with sharing并不能对字段级别(FieldLevelSecurity)的权限生效(仍然是System Mode),
需要取得字段的权限,如果没有Profile和PermissionSet设置的权限,那么就自动报错



解决办法:使用WITH SECURITY_ENFORCED关键词来报错,如果没有权限

关于WITH SECURITY_ENFORCED

在官方说明文档里面是这么记述的

If any fields or objects referenced in the SOQL SELECT query using WITH SECURITY_ENFORCED are inaccessible to the user, a System.QueryException is thrown, and no data is returned.

如果在SOQL语句的SELECT子句里面,有任何的字段没有可读权限,那么系统就自动抛出System.QueryException

在使用WITH SECURITY_ENFORCED关键词,强制Apex识别字段或者Object权限的时候,

应该使用Try和Catch语句来捕捉异常。


LWC Html代码如下

<template>
    <lightning-card title='Custom Table' icon-name="custom:custom11">
        <table class="slds-table slds-table_cell-buffer slds-table_bordered">
            <thead>
                <tr class="slds-line-height_reset">
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Account Name">Account Name</div>
                  </th>
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Parent Account">Parent Account</div>
                  </th>
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Type">Industry</div>
                  </th>
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Rating">Rating</div>
                  </th>
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Phone">Phone</div>
                  </th>
                  <th class="" scope="col">
                    <div class="slds-truncate" title="Ownership">Ownership</div>
                  </th>
                </tr>
              </thead>
              <tbody>
                <template for:each={records} for:item ='record'>
                <tr class="" key = {record.Id}>
                        <td data-label="Account Name">
                            <div class="slds-cell-wrap"><a href="javascript:void(0);">{record.Name}</a></div>
                        </td>
                        <td data-label="Parent Account">
                            <div class="slds-cell-wrap"><a href="javascript:void(0);">{record.ParentId}</a></div>
                        </td>
                        <td data-label="Industry">
                            <div class="slds-cell-wrap">{record.Industry}</div>
                        </td>
                        <td data-label="Rating">
                            <div class="slds-cell-wrap">{record.Rating}</div>
                        </td>
                        <td data-label="Phone">
                            <div class="slds-cell-wrap">{record.Phone}</div>
                        </td>
                        <td data-label="Ownership Name">
                            <div class="slds-cell-wrap">{record.Ownership}</div>
                        </td>
                </tr>
                </template>
            </tbody>
        </table>
    </lightning-card>
</template>


LWC JS代码如下

import { LightningElement,api,track,wire } from 'lwc';
import getAllAccounts from '@salesforce/apex/customTable.getAllAccounts';
export default class CustomTable extends LightningElement {
    @api records;
    @api errors;

    @wire(getAllAccounts,{
     }
    )
    wiredCases({
        data,error
    }){
    if(data){
        this.records = data;
        this.errors = undefined;
    }
    if(error){
        this.errors = error;
        this.records = undefined;
        }
    }
}


Apex代码如下

public with sharing class customTable {
    @AuraEnabled(cacheable = true)
    public static List<Account> getAllAccounts(){
        List<Account> accList =[Select Id,Name,Ownership,
                                Industry,Rating,ParentId,Phone FROM Account limit 10 ];
        return accList;
    }
}


用户的权限如下


displayAccountRecord.js-meta.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>

    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__UtilityBar</target>
        <target>lightning__FlowScreen</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>

</LightningComponentBundle>


Apex代码如下

public with sharing class customTable {
    @AuraEnabled(cacheable = true)
    public static List<Account> getAllAccounts(){
        List<Account> accList =[Select Id,Name,Ownership,
                                Industry,Rating,ParentId,Phone FROM Account WITH SECURITY_ENFORCED limit 10 ];
        return accList;
    }
}



LWC执行效果如下(大家看到了,任何数据都不会被取出来


再来看一下Debug Log的内容(我们可以看到,系统抛出异常

Insufficient permissions: secure query included inaccessible field)





59.0 APEX_CODE,DEBUG;APEX_PROFILING,NONE;CALLOUT,NONE;DB,NONE;NBA,NONE;SYSTEM,NONE;VALIDATION,NONE;VISUALFORCE,NONE;WAVE,NONE;WORKFLOW,NONE
19:17:34.5 (5071761)|USER_INFO|[EXTERNAL]|0055h000007pzoS|yusizhong1234@gmail.com|(GMT+09:00) 日本標準時 (Asia/Tokyo)|GMT+09:00
19:17:34.5 (5189218)|EXECUTION_STARTED
19:17:34.5 (5218000)|CODE_UNIT_STARTED|[EXTERNAL]|apex://customTable/ACTION$getAllAccounts
19:17:34.5 (6137783)|CODE_UNIT_STARTED|[EXTERNAL]|01p5h00000SDeNW|customTable.getAllAccounts()
19:17:34.5 (9027620)|EXCEPTION_THROWN|[4]|System.QueryException: Insufficient permissions: secure query included inaccessible field
19:17:34.5 (9485524)|FATAL_ERROR|System.QueryException: Insufficient permissions: secure query included inaccessible field

Class.customTable.getAllAccounts: line 4, column 1
19:17:34.5 (9515490)|FATAL_ERROR|System.QueryException: Insufficient permissions: secure query included inaccessible field

Class.customTable.getAllAccounts: line 4, column 1
19:17:34.5 (9566793)|CODE_UNIT_FINISHED|customTable.getAllAccounts()
19:17:34.5 (9962174)|CODE_UNIT_FINISHED|apex://customTable/ACTION$getAllAccounts
19:17:34.5 (9975819)|EXECUTION_FINISHED



参考文章

Filter SOQL Queries Using WITH SECURITY_ENFORCED

 https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_with_security_enforced.htm 

关注 收藏