Discover Spring 20 Release features! We are sharing release highlights for Developers (and Admins), curated and published by Salesforce product experts, as part of Learn MOAR
1 of 26
Download to read offline
More Related Content
Field Level Security - Spring 20
1. Field Level Security in Apex
Learn MOAR in Spring 20
Rajesh Gupta
Senior Tech Lead
iBirds Software Services Pvt. Ltd., Ajmer
LinkedIn: https://www.linkedin.com/in/bitrajindia
2. Salesforce provides a comprehensive and flexible data security model to secure data at
different levels....
3. In Salesforce
Data is stored in three key constructions:
Objects
Fields
Records
As a Admin, you can control WHO SEE WHAT using Sharing rules, field and object
permissions.
4. Salesforce uses
Object-level : Profiles and Permission sets.
Field-level : Profiles also control field-level access.
Record-level security : OWD, Role, Sharing Rules, Manual Sharing
5. In Apex
public With Sharing class Sharingclass
{
//code
}
public Without Sharing class nonsharing
{
//code
}
With sharing keywords when declaring a class enforces Sharing Rules, but not object
and field-level permissions
6. Using Schema Methods
Using WITH SECURITY_ENFORCED clause
Using stripInaccessible Method
There are some ways in which you can enforce object-level and field-level
permissions in Apex.
7. Check if the Email field on the Contact Object is accessible/readable by the logged in user.
if (Schema.sObjectType.Contact.fields.Email.isAccessible()) {
Contact c = [SELECT Email FROM Contact WHERE Id= :Id];
}
For example,
8. Imagine that you have a bunch of fields in your query, and you have inner
queries . This if statement becomes complex to maintain.
Drawback:
9. Using WITH SECURITY_ENFORCED clause
Starting Spring 20, the WITH SECURITY_ENFORCED clause can be
used in SOQL queries to enforce field and object level security
permissions in Apex code, including subqueries and cross-object
relationships.
Field-level permissions are checked for all the fields that are retrieved in
the SELECT clause(s) of the query. Since this clause only works inside
an SOQL query, its only useful when you want to check for read access
on a field
10. Using WITH SECURITY_ENFORCED clause
Example 1:
List<Account> act1 = [ SELECT Id, Name, (SELECT LastName FROM Contacts)
FROM Account WHERE Name like 'Acme'
WITH SECURITY_ENFORCED ];
The above query will return the Id and Name of Accounts, and the LastName of the related
contacts, only if the user has read access to all of these three fields. If the user doesnt have
access to at least one of these fields, the query throws a System.QueryException exception,
and no results are returned. As a best practice, SOQL queries that use this clause, have to
be enclosed in a try/catch block, so that errors can be gracefully handled.
11. Using WITH SECURITY_ENFORCED clause
try{
List<Account> act1 = [ SELECT Id, Name, (SELECT LastName FROM Contacts)
FROM Account
WHERE Name like 'Acme'
WITH SECURITY_ENFORCED
];
}
catch(System.QueryException) {
//TODO: Handle Errors
}
12. Using WITH SECURITY_ENFORCED clause
Example 2:
List<Contact> contacts = [SELECT Id, Name, BirthDate
FROM Contact
WHERE Picture_URL__c != null WITH SECURITY_ENFORCED];
However, it is important to note that this clause doesnt verify field-level
security for fields used in the WHERE clause of the query. For example, if a
user doesnt have access a custom field called Picture_URL__c on the
Contact object, the below query doesnt throw an error, and the results are
returned as usual.
13. Using stripInaccessible Method
The stripInaccessible method from the new Security class to enforce field and
object level security in Apex.
Like the name suggests, this method can be used to strip the fields from
sObject lists to which the user doesnt have appropriate access, depending on
the operation being performed.
stripInaccessible(System.AccessType accessCheckType, List<sObject>
sourceRecords, [Boolean enforceRootObjectCRUD])
14. Using stripInaccessible Method
accessCheckType: This parameter defines the type of field-level access check to be
performed. It accepts System.AccessType enum values: CREATABLE, READABLE,
UPDATABLE, UPSERTABLE.
sourceRecords: A list of sObjects to be checked for fields that arent accessible in the
context of the current users operation.
enforceRootObjectCRUD: An optional parameter that indicates whether object-level access
check has to be performed. If set to true, and the user doesnt have the necessary CRUD
permissions on the object, this method throws an exception. It defaults to true.
15. Using stripInaccessible Method
This method returns an object of type SObjectAccessDecision. You use the
getRecords() method to access the list of sObjects which are stripped of
fields that fail the field-level security checks for the current user
For error handling purposes, you can use the getRemovedFields() method to
access a map of sObject types and their corresponding inaccessible fields.
16. Using stripInaccessible Method
Here is an example of a DML operation, where the current user doesnt have access to a
custom field Picture_URL__c on the Contact Object:
List<Contact> contacts = new List<Contact>{
new Contact(FirstName='Jane', LastName='Doe', Picture_URL__c='someurl'),
new Contact(FirstName='John', LastName='Doe', Picture_URL__c='someurl'),
};
// Strip fields that are not creatable
SObjectAccessDecision decision =
Security.stripInaccessible(AccessType.CREATABLE,contacts);
18. Using stripInaccessible Method
The DML operation written above runs successfully without exceptions, but the Picture URL
field on the inserted records would be blank because the current user doesnt have
appropriate permissions on it, therefore the value has been stripped off. However, if the user
lacked the create permission on the Contact object itself, the DML statement would throw an
exception.
Here is another example of the methods usage in a query operation, where the current user
doesnt have access to a custom field Picture_URL__c on the Contact Object.
20. Inaccessible fields are removed from the query result, therefore those fields would return
a NULL value.
If you are using the stripInaccessible method on a list of sObject records that have already
been retrieved by a query, remember to use the getRecords() method to access the list of
records with inaccessible fields removed. The original list of records is not updated by the
stripInaccessible method and would still contain the values of inaccessible fields.
22. To sum up, this method can be used to:
Strip fields from query results that the user doesnt have read access to.
Remove inaccessible fields before a DML operation without causing an exception.
Sanitize sObjects that have been deserialized from an untrusted source.
Using stripInaccessible Method
23. Summary
These new techniques make the code less verbose and more efficient.
The WITH SECURITY_ENFORCED clause can be used directly in an SOQL query to
check for read access on fields, and the query will throw an exception if a single field isnt
accessible.
stripInaccessible method can be used in read, create, update and upsert operations to strip
the fields from sObject Lists that are inaccessible.
24. Points To Remember -
stripInaccessible method is a preview and isnt part of the Services under your master
subscription agreement with Salesforce. This feature is for evaluation purposes only, not for
production use. Its offered as is and isnt supported, and Salesforce has no liability for any
harm or damage arising out of or in connection with it.
The return list is identical to the source records, except that the fields that are inaccessible to
the current user are removed. the getRecords method contain records in the same order as
the sObjects in the sourceRecords parameter of the stripInaccessible method.
The ID field is never stripped by the stripInaccessible method to avoid issues when
performing DML on the result.
25. Points To Remember -
The ID field is never stripped by the stripInaccessible method to avoid issues when
performing DML on the result.
The stripInaccessible method doesnt support AggregateResult SObject. If the source records
are of AggregateResult SObject type, an exception is thrown.