Tag Archives: Apex

Salesforce Two-Factor Authentication Using Login Flow

For higher security standards one of the best practices to implement is two-factor authentication. This is the method of adding a second factor to the username and password, where the password is the first factor. The second factor is usually done with a random and time-based one-time password (TOTP), generated on an approved mobile device or an approved email address.

When a user logs in, Salesforce considers the user’s geographic location and browser. If they’re not recognized, Salesforce prompts the user to verify their identity using the highest-priority verification method available for that user.
The following is the order of priority for verification methods.

  • Verification code generated by a mobile authenticator app connected to the user’s account.
  • Verification code sent via SMS to the user’s verified mobile device.
  • Verification code sent via email to the user’s email address.

The user enters the code as a secondary verification of their identity. After verification, the user doesn’t need to provide this information again, unless they log in from a browser or location that isn’t verified by Salesforce.

But sometimes we require a second level of authentication on every login for stronger identity verification. We can enable Two-factor authentications for users by adding “Two-Factor Authentication for User Interface Logins” permission through a Profile or a Permission Sets.

The following are the verification methods:

  • Verification code generated by a mobile authenticator app connected to the user’s account.
  • Verification code sent via SMS to the user’s verified mobile device.
  • Verification code sent via email to the user’s email address.

Here is an example of two-factor authentication using login flow, which will send an one-time password (OTP) via email to the user’s email address.

  1. Create an Apex class “OTPGenerator”:
    This class provides a random 6 digit “one-time password”(OTP).

    global class OTPGenerator implements Process.Plugin
    {    
        global Process.PluginResult invoke(Process.PluginRequest request)
        {   
            Map<String, Object> result = new Map<String, Object>();  
            
            String rand = string.valueof(Math.abs(Crypto.getRandomInteger()));
            String otp = rand.substring(0,6);
            result.put('OTP', otp);
            
            return new Process.PluginResult(result);
        }
    
        global Process.PluginDescribeResult describe()
        {
            Process.PluginDescribeResult result = new Process.PluginDescribeResult();
            result.description = 'This plug-in generates a radnom 6-digits code';
            result.tag = 'Identity';
            
            result.inputParameters = new List<Process.PluginDescribeResult.InputParameter> {};
            
            result.outputParameters = new List<Process.PluginDescribeResult.OutputParameter> {
                new Process.PluginDescribeResult.OutputParameter('OTP',
                    Process.PluginDescribeResult.ParameterType.STRING)
            };
               
            return result;
        }
    }
    
  2. Click on Setup | App Setup | Create | Workflows & Approvals | Flows
  3. Click on New Flow, it will open flow canvas.
  4. Create “LoggedInUserId” Formula – Drag and drop Formula from Resources – Give the Unique name “LoggedInUserId” – And put the value “$User.Id” as shown in the below screenshot.
    1
  5. Create “OTP” Variable – Drag-and-drop Variable from Resources – Give the Unique name “OTP” as shown in the below screenshot.
    2
  6. Create “UserEmailAddress” Variable – Drag and drop Variable from Resources – Give the Unique name “UserEmailAddress” as shown in the below screenshot.
    18
  7. Create “UserFirstName” Variable – Drag and drop Variable from Resources – Give the Unique name “UserFirstName” as shown in the below screenshot.
    17
  8. Create “UserName” Variable – Drag and drop Variable from Resources – Give the Unique name “UserName” as shown in the below screenshot.
    16
  9. Create “TwoFactorAuthenticationLoginOTP” Text Template – Drag and drop Text Template from Resources – Give the Unique name “TwoFactorAuthenticationLoginOTP” – And put the “{!OTP}” variable any where in value for OTP as shown in the below screenshot.
    4
  10. Drag-and-drop “Record Lookup” from Palette(Data) – Give the Name “Get User Info”.
    • In Look Up – Select Standard Object “User”
    • Enter criteria Id = {!LoggedInUserId}
    • Assign Logged in User field value to variables.
      • Email to {!UserEmailAddress}
      • FirstName to {!UserFirstName}
      • Username to {!UserName}

    3

  11. Get random 6 digit “one-time password”(OTP) – Drag-and-drop “OTPGenerator” from Palette(Identity) – Give the name “Generate Random OTP”
    • Map the Source – Target as OTP – {!OTP} in outputs as shown in the below screenshot.

    5

  12. Send the OTP to the User – Drag-and-drop “Send Email” from Palette(Static Action) – Give the name “Send Email”
    • For Body add the Text Template “TwoFactorAuthenticationLoginOTP”.
    • Enter Subject “Login One Time Password”.
    • For Email Address (Comma-separated) Select {!UserEmailAddress} variable, as shown in the following screenshot.

    6

  13. Now allowing user to enter OTP – Drag and drop “Screen” element from Palette(User Interface) – Give the name “Get OTP”
    • Add a Textbox to enter OTP – Give Unique name “OTPInput” as shown in the below screenshot.

    7

  14. To verify OTP(Generated by “OTPGenerator” Class) – Drag and drop “Decision” element from Palette(Logic) – Give the name “OTP Validation”. On the window to check whether variable {!OTP} is equal to Screen Input element {!OTPInput}. If both the values is not same, then it means don’t allow user to login into Salesforce.
    8
  15. For invalid OTP add a screen to show error message –  Drag and drop “Screen” element from Palette(User Interface) – Give the name “Invalid OTP”
    • Add a “Display Message” – Give the name “InvalidTitle” – With the value “Invalid OTP!” as shown in the below screenshot.

    9

  16. Set “Record Lookup” (Get User Info) element as Start element as shown in below screenshot.
    21
  17. Finally the Flow will look like the following screenshot.
    20
  18. Save the flow with name “Two Factor Authentication Using Email” then Activate it and close the canvas.
  19. Now To create a Login Flow follow the below instructions:
    • Click on Name | SetupAdministration Setup | Security Controls | Login Flows
    • Click on the New button.
    • Enter the Login Flow Name, Select the flow, User license and Profile, It will look like the below screenshot.

    19

Now its time to test the “Two Factor Authentication”. To test it follow the below instructions:

  • Login into Salesforce through User who have same profile that you have used in Login Flow, In my case it’s “Custom Standard User”. After Successful login you will receive an email, it will look like the below screenshot.
    10
  • Enter OTP(One-time Password) onto the screen input field (i.e. OTP) and click on the Next Button, as shown in the below screenshot.
    11
  • If Security Code is matched then you will redirect to Salesforce Home Page else it will display an error message as shown in the below screenshot.
    12

Note : I will suggest to implement and test it in your Developer or Sandbox org, and then move it to Production.

 

What is the difference between apex Trigger.New and Trigger.old?

Trigger.new : Returns a list of the new versions of the sObject records. Note that this sObject list is only available in insert and update triggers, and the records can only be modified in before triggers.

Trigger.old : Returns a list of the old versions of the sObject records. Note that this sObject list is only available in update and delete triggers.

How to Use Debug Logs in Salesforce

A debug log records database operations, system processes, and errors that occur when executing a transaction or while running unit tests. The system generates a debug log for a user every time that user executes a transaction that is included in the filter criteria. We can monitor specific users in Debug log by adding them to list of Monitored Users.

Add Users to the debug log:

Step1: Go to Setup, click Monitoring | Debug Logs.

1

Step2: Click on New button to add User.

2

Step3: Add User and Save.

3

4

Debug log can contain information about:

  • Database changes
  • HTTP callouts
  • Apex errors
  • Resources used by Apex
  • Automated workflow process, such as :
    • Workflow rules
    • Assignment rules
    • Approval processes
    • Validation rules

Debug Log Categories:
We can specify the following log categories. The amount of information logged for each category depends on the log level:

Log Category Description
Database Includes information about database activity, including every data manipulation language (DML) statement or inline SOQL or SOSL query.
Workflow Includes information for workflow rules, flows, and processes, such as the rule name, the actions taken, and so on.
Validation Includes information about validation rules, such as the name of the rule, whether the rule evaluated true or false, and so on.
Callout Includes the request-response XML that the server is sending and receiving from an external Web service. This is useful when debugging issues related to using Force.com Web services API calls.
Apex Code Includes information about Apex code and can include information such as log messages generated by DML statements, inline SOQL or SOSL queries, the start and completion of any triggers, and the start and completion of any test method, and so on.
Apex Profiling Includes cumulative profiling information, such as the limits for your namespace, the number of emails sent, and so on.
Visualforce Includes information about Visualforce events, including serialization and deserialization of the view state or the evaluation of a formula field in a Visualforce page.
System Includes information about calls to all system methods such as the System.debug method.

Debug Log Levels:
We can specify the following log levels.

  • ERROR
  • WARN
  • INFO
  • DEBUG
  • FINE
  • FINER
  • FINEST

Note: The following are the limits for debug logs:

  • Once a user is added, that user can record up to 20 debug logs. After a user reaches this limit, debug logs stop being recorded for that user. Click Reset on the Monitoring Debug logs page to reset the number of logs for that user back to 20. Any existing logs are not overwritten.
  • Each debug log can only be 2 MB. Debug logs that are larger than 2 MB are reduced in size by removing older log lines, such as log lines for earlier System.debug statements. The log lines can be removed from any location, not just the start of the debug log.
  • Each organization can retain up to 50 MB of debug logs. Once your organization has reached 50 MB of debug logs, the oldest debug logs start being overwritten.

Example:
Here is a sample debug log I’ve written it in an Apex class, which is the controller of a visualforce page.

 System.debug('This is a test debug log'); 

Now execute that visualforce page on which the code is written.

After execution again go to the Debug Logs page, where the user is added. You will see the screen like below:

5

As you can see now that new row is added in “Debug Logs” section. click on the “view” button.

6