Named Credentials PER USER with OAuth 2.0

In this post, we will implement the Named Credentials with Per User Identity Type with OAuth 2.0. In the previous post, we implemented Named Credentials with OAuth2.0 using Named Principal Identity Type which you can check here. We will use the same code and configuration like Connected App and Auth. Provider implemented in the previous post. So I recommend you to check it, as this post will not explain it. Prior to that post, we implemented Named Credentials using Password Authentication Identity Type which you can check here.

Named Principal applies the same credential or authentication configuration for the entire org, while Per User authentication provides access control at the individual user level. Let’s hop into the implementation. Hence if we use the Per User identity type, only specific users who have access to Named Credentials can use the External Service. And each user needs to authenticate themselves in order to use the External System.

Implementation

In this implementation, we will create a REST Web Service in Salesforce Org which will return the list of Accounts. We will call that Web Service from another Salesforce Org to fetch the list of Accounts and display it on UI.

Named Credentials PER USER
Named Credentials PER USER

First, we need to create a REST Web Service to return the list of Accounts in target org.

AccountRest.apxc

@RestResource(urlMapping='/AccountService/*')
global class AccountRest {
     
    @HttpGet
    global static list<Account> fetchAccounts(){
        return [SELECT Name, AccountNumber, Phone, Website FROM Account order by CreatedDate DESC LIMIT 10];
    }
}

Connected App and Auth. Provider

We need to create a Connected App in target Salesforce Org to enable OAuth 2.0. Then we need to setup Auth. Providers in source Org for the Authentication. Please check the earlier post which explains these steps in detail with implementation.

Named Credentials PER USER

We have to create a Named Credentials. Type Named Credentials in Quick Find box and click on Named Credentials. Enter the endpoint of our Rest Web Service in the URL field. Select Identity Type as Per User. The Per User authentication provides access control at the individual user level. For the Authentication Protocol, select OAuth 2.0 and for the Authentication Provider, select Auth. Provider we just created earlier. Keep the Scope field blank as it will override the scopes that we mentioned in the Auth. Provider. Do not check Start Authentication Flow on Save checkbox as Authentication flow will be executed by an individual user. Keep the Generate Authorization Header checkbox checked and hit Save.

Named Credentials PER USER
Named Credentials PER USER

Once the Named Credentials is created, we need to provide access of Named Credentials to users using either Profiles or Permission Sets. Navigate to any profile and click on the Edit button under Enabled Named Credential Access. Add the Named Credentials created earlier from Available Named Credentials to Enabled Named Credentials. Click Save.

Enable Named Credentials
Enable Named Credentials

Authentication Settings for External Systems

Now, an individual user has to set up the Authentication Setting for External Systems and execute the Authentication flow. Click on the View Profile button on the top right corner and then click on Settings. Click on Authentication Settings for External Systems under My Personal Information in the left sidebar.

Authentication Settings for External Systems
Authentication Settings for External Systems

Then, click on New to create an Authentication Settings. Select Named Credential as an External System Definition. For the Named Credential field, selected the Named Credential created earlier. Select OAuth 2.0 as an Authentication Protocol. Authentication Provider should be auto-populated based on the Named Credentials selected. Select Start Authentication Flow on Save which will trigger the Authentication flow. Click Save.

Authentication Settings for External Systems
Authentication Settings for External Systems

Authentication Flow

After clicking Save, the user will be redirected to the Login page for the target org. Enter the Credentials of target org. It will ask permission to access your data based on the Scopes we entered in the Connected App. Click Allow and you will be redirected to the Named Credentials page. The Authentication Status field should display as Authenticated as <some username>.

Named Credentials PER USER
Named Credentials PER USER

Code

Create a Lightning Component that will have a table to display a list of records and a Button to call the Apex controller method. Apex controller method will hit the endpoint using Named Credentials to fetch the list of records.

AccountManager.cmp

<aura:component controller="AccountManager" implements="flexipage:availableForAllPageTypes">
    <!-- attributes -->
    <aura:attribute name="data" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    <lightning:card title="Named Credentials - OAuth 2.0 Implementation (PER USER Identity Type)">
        <div class="slds-p-left_x-small">
            <lightning:button label="Get Accounts from External System" onclick="{!c.getAccounts}" /> <br/><br/>
            <div style="height:315px">
                <lightning:datatable keyField="id" data="{!v.data }" columns="{!v.columns }"
                        hideCheckboxColumn="true"/>
            </div>
        </div>
    </lightning:card>
</aura:component>

AccountManagerController.js

({
    getAccounts: function (component, event, helper) {
        helper.getAccountsHelper(component, event, helper);
    }
});

AccountManagerHelper.js

({
	getAccountsHelper : function(component, event, helper) {
		var action = component.get("c.fetchAccounts");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                
                // Set the columns for Datatable
                component.set('v.columns', [
                    {label: 'Name', fieldName: 'Name', type: 'texts'},
                    {label: 'Account Number', fieldName: 'AccountNumber', type: 'text'},
                    {label: 'Phone', fieldName: 'Phone', type: 'phone', 
                        cellAttributes: { iconName: 'utility:phone_portrait' }},
                    {label: 'Website', fieldName: 'Website', type: 'url'}
                ]);
                
                component.set("v.data", response.getReturnValue());
            }
            else {
                console.log("Failed with state: " + state);
            }
        });
        $A.enqueueAction(action);
	}
})

AccountManager.apxc

public class AccountManager {
    
    @AuraEnabled
    public static list<Account> fetchAccounts(){
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('callout:AccountCreds/apexrest/AccountService');
        request.setMethod('GET');        
        HttpResponse response = http.send(request);
        if (response.getStatusCode() == 200) {
            list<Account> results = (list<Account>) JSON.deserialize(response.getBody(), list<Account>.class);
            return results;
        } else {
            System.debug('### ' +response.getBody());
        }
		return null;
    }
}

This is how we can use Named Credentials PER USER Identity Type with OAuth 2.0. Please Subscribe if you don’t want to miss new posts. Thanks!

Check Salesforce’s official documentation here to know more about Named Credentials.

Leave a Comment