需求: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