Salesforce数据安全DEMO (OLS / FLS - WITH SECURITY_ENFORCED / RLS - Sharing关键字)

318 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

数据安全在Salesforce项目实施中是一个很大的话题,本文将以Developer的视角,收录并验证Apex Code中是否Respect Sharing Model和User Permission的关键技术要素。要点如下:
#1. 如何通过合理使用Sharing关键字控制代码是否尊重Sharing Model;
#2. 如何通过SOQL来控制返回数据是否尊重User Permission设置;

RLS - Sharing关键字矩阵

研究背景:在做房地产项目时,需要将定制版的系统抽成一套模板,供不同公司共Org使用,因此需要在记录级别权限上通过Compang ID来隔离数据。由于使用的是Partner Community License,有些对象记录权限需要部分访问,而有些需要全部访问,因此需要通过合理使用Sharing相关关键字来实施业务。以下是嵌套使用关键字对RLS影响:

DEMO TIME

SOQL中WITH SECURITY_ENFORCED对OLS / FLS影响

DEMO设定:现有一Partner Community User A,2对象Account和Test__c,Profile中对2对象OLS和FLS设定如下:
Account: OLS - CUR & FLS - No access to Company_Id__c
Test__c: OLS - No access

DEMO代码:在Controller中我们没有使用Sharing关键字,因此RLS层面默认将访问所以记录。

public class A_CommunityController {
    public String soql { get;set; }
    public String msg { get;set; }
    
    public String records { get;set; }
    
    public PageReference fetchData() {
        records = '';
        msg = '';
        try {
            if(String.isNotEmpty(soql)) records = JSON.serialize(Database.query(soql));
            msg = 'success';
        }catch(Exception ex) {
            msg = ex.getMessage();
        }
		return null;        
    }
}
<apex:page showHeader="false" sidebar="false" controller="A_CommunityController" lightningStylesheets="true">
    <p style="font-size: 16px;">
        <b>Hi {!$User.UserName}, welcome to community helper page.</b>
    </p>
	<apex:form>
        <apex:pageBlock id="block" title="Get Records by entered SOQL">
        	<apex:inputTextarea label="SOQL" value="{!soql}" cols="150" rows="5"/>
            <br/>
            <apex:commandButton action="{!fetchData}" value="Query" reRender="block"/>
            <p>
                Results Here...
            </p>
            <apex:outputText id="msg" value="{!msg}"/>
            <hr/>
            <apex:outputPanel id="result">
            	<apex:outputText style="font-size: 16px;">{!records}</apex:outputText>
            </apex:outputPanel>
        </apex:pageBlock>
    </apex:form>
</apex:page>

DEMO验证:

#1. 查询Account时SOQL不含无权访问字段: ​ #2. 查询Account时SOQL含无权访问字段: ​ #3. 查询Test__c:
如果我们重新启用Test__c的CURD权限后,结果如下: ​ DEMO结论:

当查询的SOQL中的对象无Read权限或字段无Read权限,查询时都会报错:“Insufficient permissions: secure query included inaccessible field”,且无数据返回。

官方指南