Thursday, July 6, 2017

ACCESS TOKEN USING OAUTH 2.0 IN SALESFORCE

OAuth (Open Authorization) is an open protocol to allow secure API authorization in a simple and standardized way from desktop and web applications. The Force.com platform implements the OAuth 2.0 Authorization Framework, so users can authorize applications to access Force.com resources (via the Force.com REST and SOAP Web Service APIs) or Chatter resources (via the Chatter REST API) on their behalf without revealing their passwords or other credentials to those applications. Alternatively, applications can directly authenticate to access the same resources without the presence of an end user.

In this blog, I will be specifying different steps which we need to perform in order to generate Access token for Salesforce org. We will be using 2 different developer org. In org 1, we will be writing all code to generate access token for another org.

In order to access token from different org and storing different required information, we will create custom object (External_Application__c) and create different fields mentioned below:

Field Label
Field Name
Data Type
Access Token
Access_Token__c
Text Area(255)
Application Name
Application_Name__c
Text(255) (Unique Case Insensitive)
Authorization Server Response
Authorization_Server_Response__c
Long Text Area(32768)
Callback URL
Callback_URL__c
Text Area(255)
Client ID
Client_ID__c
Text Area(255)
Consumer secret
Consumer_Key__c
Text Area(255)
ID
ID__c
Text Area(255)
Instance URL
Instance_URL__c
Text Area(255)
Issued at
Issued_at__c
Text Area(255)
Outh Code
Outh_Code__c
Text Area(255)
Refresh_Token
Refresh_Token__c
Text Area(255)
Salesforce Domain
Salesforce_Domain__c
Text(255)
Scope
Scope__c
Text(255)
Signature
Signature__c
Text Area(255)


Different steps involved in order to get access token:

Login to developer organization (org 2) for which you want to generate access token.
  1. Navigate to Setup  Create  Apps, and in the Connected Apps section, click New to create a new connected app and click Enable OAuth Settings to open the API section.
  2. Specify name (here I am specifying "Rest Playground"), check enable OAuth settings checkbox and specify callback URL (in my case- https://xxx.salesforce.com/apex/WebServerAuthentication?AppName=SunilKumar04). here xxx refer to domain name for example ap1,ap2 etc.
  3. You may leave “Selected OAuth Scopes” blank.
  4. Click on Save. You will get consumer key and consumer secret key. Copy these 2 keys values and store it in notepad.


Now login to developer organization (org 1) where you will be writing whole logic to find access
token for org 2.
  • Create a custom button "Refresh Access Token" in External Application object. 

  • Create a VF page “WebServerAuthentication” and apex class “WebServerAuthenticationController”.

    /*
    Details: This class will be used to get access token of other org in order to communicate to other org.
    Steps to get Access token using REST API
    1. First create Domain name in target org.
    2. Create Remote Access (or connected app) in soure org from where we are sending request. System will give Client Id(Consumer key field in Remote access) and
    Client secret(Consumer secret field in Remote access).
    3. Fetch code by specifying Client Id redirect URL (CallbackUrl specified in remote access) in request. System will prompt only once to login in target org and
    will redirect to callback URL.
    4. Fetch Code from URL and then request for Access token by specifying code,ClientId, consumer key and redirect url.
    5. Parse JSON to get access token and fields returned by target org.
    6. Update the External App field with values returned in JSON.
    */
    public class WebServerAuthenticationController {
    public String strExternalAppId{get;set;}
    public String strAuthcode{get;set;}
    public String StrAppName{get;set;}
    public External_Application__c EApp{get;set;}
    public WebServerAuthenticationController(){
    strExternalAppId=Apexpages.currentPage().getParameters().get('EAid');
    StrAppName=Apexpages.currentPage().getParameters().get('AppName');
    strAuthCode=ApexPages.currentPage().getparameters().get('code');
    EApp=new External_Application__c();
    if(StrAppName!=null && StrAppName!=''){
    for(External_Application__c ea:[select id,Client_ID__c,Salesforce_Domain__c,Consumer_Key__c,Callback_URL__c,Application_Name__c,Access_Token__c,ID__c,Instance_URL__c,Issued_at__c,Outh_Code__c,Refresh_Token__c,Signature__c from External_Application__c where Application_Name__c=:StrAppName]){
    EApp=ea;
    }
    }
    system.debug('******SSSSSS;'+EApp);
    }
    public PageReference WebServerlogin(){
    system.debug('******strAuthCode;'+strAuthCode);
    system.debug('******EApp.Client_ID__c;'+EApp.Client_ID__c);
    system.debug('******EApp.Callback_URL__c;'+EApp.Callback_URL__c);
    system.debug('******EApp.Salesforce_Domain__c;'+EApp.Salesforce_Domain__c);
    if(strAuthCode==null || strAuthCode==''){
    if(EApp.Client_ID__c!=null && EApp.Client_ID__c!='' && EApp.Callback_URL__c!=null && EApp.Callback_URL__c!='' && EApp.Salesforce_Domain__c!=null && EApp.Salesforce_Domain__c!=''){
    PageReference p1=new PageReference('https://'+EApp.Salesforce_Domain__c+'/services/oauth2/authorize?response_type=code&client_id='+EApp.Client_ID__c.trim()+'&redirect_uri='+EApp.Callback_URL__c);
    p1.setRedirect(true);
    return p1;
    }
    else{
    ApexPages.addMessage(new Apexpages.Message(ApexPages.Severity.ERROR,'Please check if Cliend ID,Callback URL and domain name or target is present in '+EApp.Application_Name__c+' record. If not, Please specify these values first.'));
    }
    }else{
    Find_access_token_Webserver();
    }
    PageReference p1=new pageReference('/'+EApp.id);
    p1.setRedirect(true);
    return p1;
    }
    public void Find_access_token_Webserver(){
    if(strAuthCode!=null && strAuthCode!='' && StrAppName!=null && StrAppName!='' && EApp.Consumer_Key__c!=null && EApp.Consumer_Key__c!=''){
    HttpRequest req=createHTTPRequest();
    HTTPResponse res=sendRequest(req);
    EApp.Authorization_Server_Response__c=res.getBody();
    System.debug(res.getBody());
    ResponseParser(res.getBody());
    update EApp;
    }
    }
    public HttpRequest createHTTPRequest(){
    EApp.Outh_Code__c=strAuthCode;
    HttpRequest req = new HttpRequest();
    String endPointURL='https://'+EApp.Salesforce_Domain__c+'/services/oauth2/token?code='+strAuthCode+'&grant_type=authorization_code&client_id='+EApp.Client_ID__c+'&client_secret='+EApp.Consumer_Key__c+'&redirect_uri='+EApp.Callback_URL__c;
    System.debug('******endPointURL:'+endPointURL);
    req.setEndpoint(endPointURL);
    req.setMethod('POST');
    return req;
    }
    public void ResponseParser(String response ){
    // Parse JSON response to get refresh_token values.
    JSONParser parser = JSON.createParser(response);
    while (parser.nextToken() != null) {
    if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)){
    String fieldName = parser.getText();
    parser.nextToken();
    if(fieldName == 'id') {
    EApp.ID__c = parser.getText();
    } else if(fieldName == 'issued_at'){
    //EApp.Issued_at__c = parser.getIntegerValue();
    } else if(fieldName == 'scope'){
    EApp.Scope__c = parser.gettext();
    } else if(fieldName == 'instance_url'){
    EApp.Instance_URL__c = parser.gettext();
    } else if(fieldName == 'refresh_token'){
    EApp.Refresh_Token__c = parser.gettext();
    } else if(fieldName == 'signature'){
    EApp.Signature__c = parser.gettext();
    } else if(fieldName == 'access_token'){
    EApp.Access_Token__c= parser.gettext();
    }
    }
    }
    }
    public HTTPResponse sendRequest(HttpRequest Req){
    Http http = new Http();
    HTTPResponse res = http.send(req);
    return res;
    }
    }
    <apex:page controller="WebServerAuthenticationController" action="{!WebServerlogin}">
    </apex:page>
  • Add custom button "Refresh Access Token"  to External Application page layout.
  • Create Remote Site Settings records. Specify domain name of org 2 for which you want to fetch access token.

  • Now create a External Application records. Specify consumer key (generated while creatin connected app in org 2) in client id field. Enter consumer secret and callback URL as present in connect app record in org 2.


Now we ready to generate access token which for org 2. Go to detail page of  record which you created. I have created record with name as "SunilKumar04".  Click on Refresh Access Token.
System will redirect you to salesforce login page. Enter the credential of org 2 for which you want access token. After logging, if system ask any permission then click on Allow button. After that you will be redirected to org 1 and you can see the response details on External Application record detail page.


Notes:
  • If you are integrating 2 developer org, then create domain in your developer org and use domain URL  as endpoint URL in Httprequest.
  • You can connect to different org. Create different records in External Application object for different org.
  • For more detailed information on obtaing access token, please refere below URL  https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

No comments:

Post a Comment