5

I am trying to implement OAuth 2.0 Username-Password Flow and below is my code and debug log - any help is appreciated.

Http httpProtocol = new Http();   
HttpRequest request = new HttpRequest();
request.setHeader('Content-Type', 'application/json;');
request.setEndPoint('https://test.salesforce.com/services/oauth2/token');
request.setMethod('POST');
String strbody = '{"grant_type":"Password", "password":"MY PASSWORD + TOKEN", "username":"SANDBOX USER NAME",  "client_secret":"secret",   "client_id":"Client id from remote setttings"}';
request.setBody(strbody);
HttpResponse response = httpProtocol.send(request);
String jsonInput = response.getBody();
system.debug('jsonInput===>'+jsonInput);

Debug log -

15:55:38.068 (68324000)|SYSTEM_METHOD_ENTRY|[5]|System.HttpRequest.setMethod(String)
15:55:38.068 (68346000)|SYSTEM_METHOD_EXIT|[5]|System.HttpRequest.setMethod(String)
15:55:38.068 (68350000)|STATEMENT_EXECUTE|[6]
15:55:38.068 (68356000)|HEAP_ALLOCATE|[6]|Bytes:357
15:55:38.068 (68381000)|VARIABLE_ASSIGNMENT|[6]|strbody|"{\"grant_type\":\"Passw (337 more) ..."
15:55:38.068 (68387000)|STATEMENT_EXECUTE|[7]
15:55:38.068 (68407000)|SYSTEM_METHOD_ENTRY|[7]|System.HttpRequest.setBody(String)
15:55:38.068 (68440000)|SYSTEM_METHOD_EXIT|[7]|System.HttpRequest.setBody(String)
15:55:38.068 (68445000)|STATEMENT_EXECUTE|[8]
15:55:38.068 (68478000)|SYSTEM_METHOD_ENTRY|[8]|System.Http.send(APEX_OBJECT)
15:55:38.068 (68568000)|CALLOUT_REQUEST|[8]|System.HttpRequest[Endpoint=https://test.salesforce.com/services/oauth2/token, Method=POST]
15:55:38.483 (483258000)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:219
15:55:38.483 (483399000)|CALLOUT_RESPONSE|[8]|System.HttpResponse[Status=Bad Request, StatusCode=400]
15:55:38.483 (483424000)|HEAP_ALLOCATE|[8]|Bytes:96
15:55:38.483 (483444000)|SYSTEM_METHOD_EXIT|[8]|System.Http.send(APEX_OBJECT)
15:55:38.483 (483615000)|VARIABLE_ASSIGNMENT|[8]|response|"System.HttpResponse[Status=Bad Request, StatusCode=400]"|0x1b22c3f1
15:55:38.483 (483627000)|STATEMENT_EXECUTE|[9]
15:55:38.483 (483666000)|SYSTEM_METHOD_ENTRY|[9]|System.HttpResponse.getBody()
15:55:38.483 (483742000)|HEAP_ALLOCATE|[9]|Bytes:81
15:55:38.483 (483751000)|SYSTEM_METHOD_EXIT|[9]|System.HttpResponse.getBody()
15:55:38.483 (483780000)|VARIABLE_ASSIGNMENT|[9]|jsonInput|"{\"error\":\"unsupporte (61 more) ..."
15:55:38.483 (483786000)|STATEMENT_EXECUTE|[10]
15:55:38.483 (483794000)|HEAP_ALLOCATE|[10]|Bytes:13
15:55:38.483 (483980000)|HEAP_ALLOCATE|[10]|Bytes:94
15:55:38.483 (483999000)|SYSTEM_METHOD_ENTRY|[10]|System.debug(ANY)
15:55:38.484 (484025000)|USER_DEBUG|[10]|DEBUG|jsonInput===>{"error":"unsupported_grant_type","error_description":"grant type not supported"}

2 Answers 2

4
public class TestCallout {


     public static  void TestCallout(){


    String clientId = '3MVG982oBBDdwyHirurznY0bXVCZCrB6.9sxBfCGtr8ZKVUUzOPjhOcLypgBhgBugAN5XMKbPpNnQKwDCL8rk';
    String clientSecret = '9066826186886123605';
    String reqbody = 'grant_type=password&client_id=clientId&client_secret=clientSecret&username='username'&password='password';

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setBody(reqbody);
    req.setMethod('POST');
    req.setEndpoint('https://data-na3--data.cs13.my.salesforce.com/services/oauth2/token');//Note if my domain is set up use the proper domain name else use login.salesforce.com for prod or developer or test.salesforce.com for sandbox instance

    HttpResponse res = h.send(req);
    system.debug('--------'+res.getBody());

    }

    }

Just was playing around and the above code works for me without any issue .Also agree with metadaddy that content-type in http header can be set to application/x-www-form-urlencoded as best practice .

4
  • @PrafullaPatil If you are thinking of using this for integration i would say big no to this approach.This defeats process of authentication through oauth.You can ask the user to enter crendentials himself and then store oauth token somewhere in object and also there are ways of refreshing this token as well .Refer wiki.developerforce.com/page/… Jan 4, 2013 at 4:12
  • @metadaddy Thanks for this article wiki.developerforce.com/page/… has helped lot in understanding oauth principles and also thanks for all your blog post on developer force . Jan 4, 2013 at 4:14
  • is there any way I can do this without using username and password, with just clientSecret and clientId ? I will be using this for salesforce to salesforce integration. Jan 4, 2013 at 5:21
  • At the first callout get the token and store in custom object and then only first time for a session you may need to make an oauth call and refresh the token if the token as expired .Read through the document wiki.developerforce.com/page/… Jan 4, 2013 at 7:00
5

There are a couple of issues in your code:

  • The content-type HTTP header should be application/x-www-form-urlencoded
  • The grant_type form parameter should be password (all lower case)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .