• Guy Farrer Fisher
  • NEWBIE
  • 0 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 8
    Replies
I'm interested if Salesforce plans on supporting the IETF BCP 212 (a.k.a. RFC 8252): https://tools.ietf.org/html/bcp212 It appears that Salesforce should support this best practice in order to increase security for mobile and desktop applications.

The best practice document recommends using a combination of the following techniques for mobile and desktop apps where the OAuth secret cannot be kept secure:
  • Use the authorization code flow for native apps instead of the implicit grant flow (or user-agent flow as Salesforce calls it)
  • Use the PKCE technique (https://tools.ietf.org/html/rfc7636) to prevent authorization code interception by other native apps
  • Use external web browser for added security instead of embedded browsers for a better user experience that is more secure
  • Instructs the native app to receiving the authorization code response by listening on local loopback address (i.e. http://127.0.0.1) or a registered custom scheme (i.e. myapp://oauth/salesforce or https://com.myapp.www/oauth/salesforce).
It looks like the Salesforce API is very close to supporting this. The current docs for "Web Server OAuth Authentication Flow" support code_challenge and code_verifier (PKCE), and it seems that the API allows me to ask for the refresh_token scope as long as I use PKCE, which is great.

The only problem I'm running into is that the settings page for my Connected App disallows the local loopback address (http://127.0.0.1) from being used because it's not https://.

The IETF BCP 212 notes in https://tools.ietf.org/html/bcp212#section-8.3
"Loopback interface redirect URIs use the "http" scheme (i.e., without Transport Layer Security (TLS)). This is acceptable for loopback interface redirect URIs as the HTTP request never leaves the device."

From what I can tell, Salesforce would be fully compatible with IETF BCP (aka RFC 8252) if an exception is made to allow redirect_uri to be http:// for the loopback IP (127.0.0.1).

Thanks for considering, I'm interested to hear if there will be official support and documentation for using this Best Current Practice.

It's also worth noting the BCP also un-recommends using the implicit grant flow for native apps: https://tools.ietf.org/html/bcp212#section-8.2

It's also worth noting that Google supports all the required parts for BCP 212, including the native/mobile app listening on 127.0.0.1:
https://developers.google.com/identity/protocols/OAuth2InstalledApp#creatingcred

As does the popular AppAuth set of auth libraries:
https://github.com/openid/AppAuth-iOS
https://github.com/openid/AppAuth-Android
https://github.com/openid/AppAuth-JS/blob/master/README.md

As a workaround for now, on a desktop app I'm using a custom scheme (myapp://oauth/salesforce), which Salesforce allows and works, but that method leaves a blank page open in the user's browser after they auth, which is confusing (https://na30.salesforce.com/_ui/identity/oauth/ui/AuthorizationPage). If we can use an non-TLS loopback address (http://127.0.0.1/oauth/salesforce) we can provide a better user experience by having control over the authorization page.
trigger AppLeadCreation on alu_Application__c (before insert, before update) {
    
    // SOQL QUERY FOR ITERATES
    Map<Id,Lead> mapLeads = new Map<Id,Lead>([SELECT Id, Email FROM Lead]);
    System.debug('mapLeads'+mapLeads);
    
    // MAP OF IDs AND EMAIL ADDRESS OF LEAD
    Map<String,Id> mapIdsWithLeadEmail = new Map<String,Id>();
    
    // MAP OF IDs AND EMAIL ADDRESS OF APPLICATION
    Map<String,Id> mapIdsWithAppEmail = new Map<String,Id>();
    
    // MAP OF LEAD IDs AND APPLICATION ID
    Map<Id,Id> mapAppIdsEmailIds = new Map<Id,Id>();
        
    for(Lead le : mapLeads.values()){       
        mapIdsWithLeadEmail.put(le.email, le.Id);
    }
    System.debug('mapIdsWithLeadEmail'+mapIdsWithLeadEmail);
    
    for(alu_Application__c app : trigger.new){
         mapIdsWithAppEmail.put(app.Email__c, app.Id);
    }
    System.debug('mapIdsWithAppEmail'+mapIdsWithAppEmail);
    try{
   
        for(Id tmp : mapIdsWithAppEmail.Values()){
           if(mapIdsWithLeadEmail.ContainsKey(mapIdsWithAppEmail.get(tmp))){ 
               mapAppIdsEmailIds.put(tmp,mapIdsWithLeadEmail.get(tmp));       //Here I getting only ID of Application record not for Lead
            } 
        }
        System.debug('mapAppIdsEmailIds'+mapAppIdsEmailIds); 
     }Catch(Exception e){
        System.debug('ERROR:' + e.getMessage());
        System.debug('ERROR:' + e.getLineNumber());
    }
    
}
In our org, there is some code which tries to update a junction object record in the process of an account merge. The junction object's primary MD relation is with the standard Account object which has been shared with the user using sharing rules and provided Read/Write Access, and for the the sceondary MD relation object which is a custom object we have provided Modify All permission in the profile. 
From the UI, the user is able to edit the junction object.  However, sometimes the DML updates fails abruptly
And the logs show error as below:

05:46:48.538 (19720154513)|DML_BEGIN|[285]|Op:Update|Type:SObject|Rows:1
05:46:48.538 (19739132178)|DML_END|[285]
05:46:48.538 (19739187685)|EXCEPTION_THROWN|[285]|System.DmlException: Update failed. First exception on row 0 with id a4h16000001AAFXAA4; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
05:46:48.538 (19739839199)|SYSTEM_MODE_EXIT|false


Sometimes, the DML fails on the account object as well. This DML statement is just after the junction object update mentioned above. And the logs show the same error as below:

12:00:12.137 (10288991686)|DML_BEGIN|[287]|Op:Update|Type:Account|Rows:1
12:00:12.137 (10289002209)|LIMIT_USAGE|[287]|DML|6|150
12:00:12.137 (10289012816)|LIMIT_USAGE|[287]|DML_ROWS|7|10000
12:00:12.137 (10289028157)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
12:00:12.137 (10321783883)|DML_END|[287]
12:00:12.137 (10321853231)|EXCEPTION_THROWN|[287]|System.DmlException: Update failed. First exception on row 0 with id 0011600001vEVpYAAW; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
12:00:12.137 (10323198564)|HEAP_ALLOCATE|[287]|Bytes:184


I'm not able to understand what exactly is cause of these DML updates failing? Could someone with knowledge on this help me resolve this.

Thanks

Hi,

 

Can we insert multiple records using the Rest API?

 

thanks.