【Apex Security and Sharing】在 Apex 中判断字段级别(FieldLevelSecurity)的权限(使用Schema方法)
2023年10月21日
文章浏览:340
需求:Apex的with sharing并不能对字段级别(FieldLevelSecurity)的权限生效(仍然是System Mode),
需要取得每一个字段,或者Object的权限




现象:自定义开发的Lightning Web コンポーネント(LWC)输出各个字段,能够显示出自己没有权限的字段


LWC Html代码如下

<template>
    <lightning-card title='Custom Table' icon-name="custom:custom11">
        <table class="slds-table slds-table_cell-buffer slds-table_bordered">
              <tbody>
                <template for:each={records} for:item ='record'>
                <tr class="" key = {record.Id}>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Account Name">项目名称:Account Name</div>
                            <div class="slds-cell-wrap"><a href="javascript:void(0);">项目值:{record.Name}</a></div>
                        </td>
                        <td data-label="Phone" >
                            <div class="slds-truncate" title="Phone">项目名称:Phone</div>
                            <div class="slds-cell-wrap" >项目值:{record.Phone}</div>
                        </td>
                        <td data-label="Ownership Name">
                            <div class="slds-truncate" title="Ownership">项目名称:Ownership</div>
                            <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>



LWC执行效果如下(电话号码能够正常显示,这明显是不正确的效果,是错误



解决办法:使用Schema方法来判断用户有没有字段(或者Object)的权限

LWC JS代码都不需要改动


Apex代码如下

public with sharing class customTable {
    @AuraEnabled(cacheable = true)
    public static List<accountListClass> getAllAccounts(){
        List<accountListClass> accountListTemp = new List<accountListClass>();

        List<Account> accList =[Select Id,Name,Ownership,
                                Industry,Rating,ParentId,Phone FROM Account limit 10 ];

        for ( Account AccountItem : accList ) {  
            accountListClass accountListClassItem = new accountListClass();
            accountListClassItem.Name = AccountItem.Name;
            accountListClassItem.ParentId = AccountItem.ParentId;
            accountListClassItem.Industry = AccountItem.Industry;
            accountListClassItem.Rating = AccountItem.Rating;
            
            //针对Phone字段的权限判断
            if (Schema.sObjectType.Account.fields.Phone.isAccessible()) {
                accountListClassItem.Phone = AccountItem.Phone;
                accountListClassItem.PhoneHasPermission = true;
            }else {
                accountListClassItem.Phone = '権限なし';
                accountListClassItem.PhoneHasPermission = false;
            }

            accountListClassItem.Ownership = AccountItem.Ownership;
            accountListTemp.add(accountListClassItem);
        }  
        
        return accountListTemp;
    }

    public class accountListClass{
        @AuraEnabled
        public  string Name{get;set;}
    
        @AuraEnabled
        public  string ParentId{get;set;}
    
        @AuraEnabled
        public  string Industry{get;set;}
    
        @AuraEnabled
        public  string Rating{get;set;}
    
        @AuraEnabled
        public  string Phone{get;set;}
        @AuraEnabled
        public  Boolean PhoneHasPermission{get;set;}
    
        @AuraEnabled
        public  string Ownership{get;set;}
    }

}


LWC Html代码如下

(在页面中,我们使用if:true Conditional Rendering来控制是否显示,

而不需要指定Style="display:none;")

<template>
    <lightning-card title='Custom Table' icon-name="custom:custom11">
        <table class="slds-table slds-table_cell-buffer slds-table_bordered">
              <tbody>
                <template for:each={records} for:item ='record'>
                <tr class="" key = {record.Id}>
                        <td data-label="Account Name">
                            <div class="slds-truncate" title="Account Name">项目名称:Account Name</div>
                            <div class="slds-cell-wrap"><a href="javascript:void(0);">项目值:{record.Name}</a></div>
                        </td>
                        <td data-label="Phone" >
                            <div class="slds-truncate" title="Phone" if:true={record.PhoneHasPermission} >项目名称:Phone</div>
                            <div class="slds-cell-wrap" if:true={record.PhoneHasPermission} >项目值:{record.Phone}</div>
                        </td>
                        <td data-label="Ownership Name">
                            <div class="slds-truncate" title="Ownership">项目名称:Ownership</div>
                            <div class="slds-cell-wrap">项目值:{record.Ownership}</div>
                        </td>
                </tr>
                </template>
            </tbody>
        </table>
    </lightning-card>
</template>
  



LWC执行效果如下(大家看到了,电话号码不再显示出来


再来看一下Debug Log的内容(我们可以看到,PhoneHasPermission是否有权限)

this.records------------------>[
{"Name":"株式会社NextStep","Phone":"権限なし","PhoneHasPermission":false},
{"Name":"NextStepTraining","Phone":"権限なし","PhoneHasPermission":false},
{"Industry":"Agriculture","Name":"SalesforceGogogo","Phone":"権限なし","PhoneHasPermission":false},
{"Name":"MyPartner","Phone":"権限なし","PhoneHasPermission":false},
{"Name":"Gogogo","Phone":"権限なし","PhoneHasPermission":false},
{"Name":"NameTest","Phone":"権限なし","PhoneHasPermission":false},
{"Name":"NextStepのCustomer","Phone":"権限なし","PhoneHasPermission":false},
{"Industry":"Biotechnology","Name":"GenePoint","Ownership":"Private","Phone":"権限なし","PhoneHasPermission":false,"Rating":"Cold"},
{"Industry":"Energy","Name":"United Oil & Gas, UK","Ownership":"Public","Phone":"権限なし","PhoneHasPermission":false},
{"Industry":"Energy","Name":"United Oil & Gas, Singapore","Ownership":"Public","Phone":"権限なし","PhoneHasPermission":false}]


参考文章


Enforcing Object and Field Permissions

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



关注 收藏