A Quick Salesforce OAuth 2.0 Usage Demonstration

A little Background:- As we know,now-a-days almost every Enterprise app(specially over web) has implemented OAuth 2.0 security framework.In salesforce development practice , there are integration scenarios with various kinds of applications.
eg. Salesforce to linkedIn ,
Salesforce to Facebook,
Salesforce to Twitter,
Salesforce to Google,
Salesforce to Salesforce,
Salesforce to any On Premise Application Integration or other way around.
Generally we have to deal with Oauth 2.0 framework.

Objective:- I will demonstrate salesforce Oauth 2.0 by connecting two salesforce dev orgs .We will use various authentication flows like web-server,user-agent,username-password etc.
Assumptions:-
1. Dev Org 1 is behaving as client application.
2. Dev Org 2 is our lovely salesforce org.
3. OAuth 2.0 framework is a guard here which needs Acess token and it will treat Dev1 Client org in Dev2 Org as guest.

Note:- Dev org 1 ultimate goal  is to get acess token to get entry into Dev org 2.

Tokens  : OAuth 2.0 understands the language of tokens, Let's simplify tokens here.

1. Authorization Code:- It is a short lived token used to get acess token and refersh token.

2. Acess Token:-This is the token we are looking for .It has a longer lifetime than AuthorizationCode.

3.Refresh Token:- It has indefinite lifetime ,This can be used to get fresh acess token once acess token gets expires.


Scenarios:- There are generally two scenarios where we intreact to OAuth 2.0 framework.


Mannual : - End user is clicks  mannually on some page to get authorized .

Automated:- Your code sends request directly to another salesforce org.

Based on above scenarios there are two distinct kinds of authentication flows available.
We will implement both flows in DEV ORG 1 which is trying to connect to DEV ORG 2.
1. Web server : It will ask End User for username and password while authentication.
2. User Name and password etc: This is seamless flow.Username and password should be stored somewhere and should be available to code.

Lot of theory.......so let's get start.

1. Create two salesforce DEV orgs eg. DEV 1 ,DEV 2.
2. In DEV 2 org ,create one connected app. Go to setup -> create -> new Connected App.
3. Enter Connected App Name,API Name,Contact Email, and check Enable OAuth setting.
4. In 'Callback URl' , paste 'https://c.ap1.visual.force.com/apex/aouthWebServerFlow'.
5. In OAuth scopes ,Give 'Full Acess' as of now and save.

We got two main important parameters in connected app ,once it gets save.

a. client key
b. client secret

There are two concepts of security where above parameters helps.

1. Authentication: Users are authenticated to what they say they are.(Through Client Id and Client Secret  )
2. Authorization:- Apps are authorized to acess resource.(Through Acess Token).


Here is the code for Web Server Flow: 

VF Page Code:-

<apex:page controller="aouthWebserverFlowController">
       <apex:form >
       <apex:outputLink value="{!fullURL}"> Get Authorization Code</apex:outputLink>
        <br/><br/>
        URL To Get Oauth Code :------->>>>>     {!fullURL}
        <br/><br/>

        <br/><br/>
        Returned oAuth Code :--------->>>>>>>>  {!oAuthCode}
        <br/>
        <apex:commandButton value="Get Acess Token" action="{!getAcessToken}"/>
         <br/><br/>
        Acess Token: ------->>>>> {!acessToken}
          <br/><br/>
        <apex:commandButton value="Get Dev 2 Org Account Metadata" action="         {!getAnotherOrgAccountMetadata}"/>
         <br/><br/>
        Dev 2 Org Meta Data: ------->>>>> {!Dev2OrgAccountMetaData }
    </apex:form>

</apex:page>


Controller Apex  Code:-

public class aouthWebserverFlowController {
    
    public string Dev2OrgAccountMetaData{get;set;}
    public string oAuthCode{get;set;}
    public String getFullURL() {
        return fullURL ;
    }


    string baseUrl ='https://login.salesforce.com/services/oauth2/authorize';
    string clientId ='&client_id=<YOUR CLIENT ID>';
    string responseType ='?response_type=code';
    string redirectURI = '&redirect_uri=https://c.ap1.visual.force.com/apex/aouthWebServerFlow';
    String clientSecret = '&client_secret=<YOUR CLIENT SECRET>';
    string fullURL = baseUrl + responseType +clientId +redirectURI ;
    
    
    string baseTokenURL = 'https://login.salesforce.com/services/oauth2/token';
    public string uRLToGetAcessToken{get;set;}
    public string acessToken{get;set;} 
    
    public aouthWebserverFlowController(){
       if(ApexPages.currentPage().getParameters().get('code')!=null){
           oAuthCode = ApexPages.currentPage().getParameters().get('code'); 
           string codeURL ='?code='+oAuthCode+'&grant_type=authorization_code';  
           uRLToGetAcessToken = baseTokenURL+codeURL+clientId+clientSecret+redirectURI;
       }
    }
    JSONWrapper jsonWrapObj;
    // Call this method to get acess token 
    public void getAcessToken(){
        //Callout to get Acess Token
        Http h = new Http();
        // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
        HttpRequest req = new HttpRequest();
        req.setEndpoint(uRLToGetAcessToken);
        req.setMethod('POST');
        req.setHeader('Content-Type','application/x-www-form-urlencoded'); 
        // Send the request, and return a response
        HttpResponse res = h.send(req);
        system.debug('-----------------------'+ res.getBody());
        
        jsonWrapObj = (JSONWrapper)JSON.deserialize(res.getBody(),JSONWrapper.class);
        acessToken =jsonWrapObj.access_token;                                              
        system.debug('-------acessToken -------'+acessToken);
       
    }
     // Call this method to get Dev2 org account metadata
    public void getAnotherOrgAccountMetadata(){
         String restResourceURL='https://ap1.salesforce.com/services/data/v20.0/sobjects/Account/describe';
       
        
        String fullRestUrl = restResourceURL;
        Http h1 = new Http();
        HttpRequest req1 = new HttpRequest();
        req1.setEndpoint(fullRestUrl);
    
        req1.setHeader('Authorization','Bearer '+acessToken);
        req1.setMethod('GET');
        // req1.setHeader('Content-Type','application/x-www-form-urlencoded'); 
        // Send the request, and return a response
        HttpResponse res1 = h1.send(req1);
        system.debug('-----------------------'+res1.getBody());
        Dev2OrgAccountMetaData =res1.getBody(); 
    }
    
    //Wrapper to store acess token
    public class JSONWrapper{
        public Integer expires_in;
        public String access_token;

   }
     

}


Here is the code for UserName- Password Flow: As this does't needs mannual intervention so there in no vf page.


Apex Class Code:

public class GetConnection{

    public GetConnection(){}
    
    public void createConnection(){
    
    string url = 'https://login.salesforce.com/services/oauth2/token';
    string clientId = '&client_id=<YOUR CLIENT ID>';
    String clientSecret ='&client_secret=<YOUR CLIENT SECRET>';
    String grantType ='?grant_type=password';
    String userName ='&username=<DEV 2 ORG USER NAME>';
    String password ='&password=<DEV 2 ORG PASSWORD>';
   
    String fullUrl = url+grantType+clientSecret+clientId+userName+password ;
    
    Http h = new Http();

      // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
    HttpRequest req = new HttpRequest();
    req.setEndpoint(fullUrl);
    req.setMethod('POST');
     req.setHeader('Content-Type','application/x-www-form-urlencoded'); 
// Send the request, and return a response
    HttpResponse res = h.send(req);
    system.debug('-----------------------'+ res.getBody());
    JSONWrapper jsonWrapObj = (JSONWrapper)JSON.deserialize(res.getBody(),JSONWrapper.class);
                                                       
    //String restResourceURL='https://ap1.salesforce.com/services/apexrest/testRestCall/v1/';
    String restResourceURL='https://ap1.salesforce.com/services/data/v20.0/sobjects/Account/describe';
    String acessToken =jsonWrapObj.access_token;
    system.debug('-------acessToken -------'+acessToken);
    String fullRestUrl = restResourceURL;
    Http h1 = new Http();
    HttpRequest req1 = new HttpRequest();
    req1.setEndpoint(fullRestUrl);
    
    req1.setHeader('Authorization','Bearer '+acessToken);
    req1.setMethod('GET');
    // req1.setHeader('Content-Type','application/x-www-form-urlencoded'); 
// Send the request, and return a response
    HttpResponse res1 = h1.send(req1);
    system.debug('-----------------------'+res1.getBody());
     
    }
    
    public class JSONWrapper{

        public Integer expires_in;
        public String access_token;

}
    
   

}

Run in developer console anonymous block using below code and check for debugs stataments in debug logs.


GetConnection conn = new GetConnection();
conn.createConnection();


Note:-Try this in your developer org and keep an eye on debug logs.

Recomended Links: Digging Deep on OAuth 2.0 on Force.com







Comments

Post a Comment

Popular posts from this blog

Salesforce To Authorize.Net Integration

Salesforce Shopify Integration