Get Hands-on With Field- and Object-Level Security and Safe Navigation Operator

Learning Objectives

After completing this unit, you’ll be able to:

  • Enforce field- and object-level security in Apex.
  • Use the safe navigation operator to avoid null pointer exceptions.

Enforce Field- and Object-Level Security with Security.StripInaccessible

What’s new?

The Security.stripInaccessible method for field- and object-level data protection is now generally available in Spring ’20. This allows developers to remove all fields from the records that the running user does not have access to. This makes it easier to allow graceful degradation of application behavior on security violation by omitting fields rather than failing.

How does it work?

Use the stripInaccessible method to strip fields that the current user can’t access from query and subquery results. Use the method to remove inaccessible fields from sObjects before a DML operation to avoid exceptions. Also, use the stripInaccessible method to sanitize sObjects that have been deserialized from an untrusted source.

The stripInaccessible method checks the source records for fields that don’t meet the field- and object-level security check for the current user and creates a return list of sObjects. The return list is identical to the source records, except that fields inaccessible to the current user are removed.

Examples:

This example removes fields from the query result that the current user does not have update access to.

  • SObjectAccessDecision securityDecision =
           Security.stripInaccessible(AccessType.UPDATABLE,
                 [SELECT Name, BudgetedCost, ActualCost FROM Campaign]
                 );

This example performs a query and then removes inaccessible fields from the query result.

List<Contact> records = [SELECT Id, Name, Phone, HomePhone FROM Contact];
SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, records);

For more information and examples, see:

Use the Safe Navigation Operator to Avoid Null Pointer Exceptions

What’s new?

Use the safe navigation operator (?.) to replace explicit, sequential checks for null references. This new operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.

How does it work?

If the left-hand side of the chain expression evaluates to null, the right-hand side is not evaluated. Use the safe navigation operator (?.) in method, variable, and property chaining. The part of the expression that is not evaluated can include variable references, method references, or array expressions.

Example:

This example first evaluates a, and returns null if a is null. Otherwise the return value is a.b.

a?.b // Evaluates to: a == null ? null : a.b

For more information and examples, see the Apex Developer Guide: Safe Navigation Operator.

Now that you’ve seen all these cool new developer features, you are ready to try them out in the Hands-on Challenge below.

Resources

Get Ready for the Hands-on Challenge

In the hands-on challenge below, you’ll have an opportunity to work with these new Apex capabilities and use Security.StripInaccessible and the Safe Navigation operator. But before we get started, a bit of setup is required.  

Our business goal is to ensure that only system administrators have access to sensitive customer information, and that other users cannot invoke our APIs that handle sensitive data. To ensure that our code is generally safe, we need to make runtime checks of field- and object-level security. As developers, we need to specifically ensure our code respects admin-defined security constraints. We’ll create a Top Secret custom field on the Contact object to store customer confidential data that standard users do not have access to.

Launch the org you’ll use for the hands-on challenge, then do the following.

  • Create a new custom field on the Contact object to establish a field that contains sensitive and confidential data.
    • Field Label: Top Secret
    • Type: Text
    • Field Name: Top_Secret
    • Length: 255
  • Uncheck the Visible box for the Standard User profile when defining field-level security.

That’s it for setup.

You’ll use the code block below for an Apex class to complete the hands-on challenge. This code is secured with conventional Schema.SObjectType field- and object-level security access checks before the SOQL query. You will refactor the code into a simplified implementation that relies on Security.stripInaccessible to apply field- and object-level security. You will also use the Safe Navigation operator to check for Null values in the result.

ApexSecurityRest code block:

@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
           throw new FunctionalException('Id parameter is required');
        }
        if (Schema.SObjectType.Contact.isAccessible()
          && Schema.SObjectType.Contact.fields.Name.isAccessible()
          && Schema.SObjectType.Contact.fields.Top_Secret__c.isAccessible()
        ) {
          List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
          if (!results.isEmpty()) {
             result = results[0];
             if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){
                 result.Description = result.Account.Name;
                 }
             }
           } else {
             throw new SecurityException('You don\'t have access to all contact fields required to use this API');
           }
           return result;
      }
      public class FunctionalException extends Exception{}
      public class SecurityException extends Exception{}
}
Keep learning for
free!
Sign up for an account to continue.
What’s in it for you?
  • Get personalized recommendations for your career goals
  • Practice your skills with hands-on challenges and quizzes
  • Track and share your progress with employers
  • Connect to mentorship and career opportunities