[SalesForce] Access rest service oauth

I've looked at this question

Server-Side REST Authentication

and many other forums with this same problem. I'm trying to access restful webservice we created in our salesforce instance with postman. I'm using this url
https://login.salesforce.com/services/oauth2/token
and these url params

grant_type=password
client_id={my id}
client_secret={my secret}
username=username@domain.com
password={password}{security token}

I'm getting this response

{
  "error": "invalid_grant",
  "error_description": "authentication failure"
}

In the connected app settings, I've added my IP under trusted IPs. I've set IP Relaxation to "Relax IP restrictions". I set permitted users to "All users may self-authorize". I added my IP address under Administer->Security Controls->Network Access.
Is there supposed to be a delimiter between password and security token in the password URL parameter? I can view my connected app through two views in salesforce.

When I go to Administer->Manage Apps->Connected Apps I see it there but when I hover the mouse over it, it doesn't say "Managed-Installed" and it doesn't have the little blue arrow next to the link. But when I click on it it says its installed

I also can view it through Develop->Remote Access which then redirects me to a page where I'm able to click on it and see the consumer key and consumer secret.

I tried sending a request from the developer console and I get the same error. I tried sending with and without the security token appended to the password. I do have the '@' character in the password, could that be causing a problem?

HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
req.setBody('grant_type=password' + 
           '&client_id=' + 'id'+
           '&client_secret=' + 'secret' +
           '&username=' + 'username@domain.com.currentdev' +
           '&password=' + 'password');
Http h = new Http();
HTTPResponse res = h.send(req);
System.debug('Body ' + res.getBody());
System.debug('Status ' + res.getStatus());
System.debug('Status code ' + res.getStatusCode());

Thanks @Eric, the problem was I'm in a test environment so I should be using test.salesforce.com not login.salesforce.com

Best Answer

Check the login history for the user and make sure you are connecting to the right url TEST vs LOGIN.

I am willing to bet that the Security Token is being required and you are not appending that to your password

You should be doing: &password={PASSWORD}{SECURITYTOKEN}

Login History Example

I used your code and once I added the IP to the allowed ranges (or appended the security token) it was successful.

HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setHeader('Content-Type','application/x-www-form-urlencoded');
req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
req.setBody('grant_type=password' + '&client_id=xyz' + '&client_secret=xyz' + '&username=un' + '&password=pw');
Http h = new Http();
HTTPResponse res = h.send(req);
System.debug('Body ' + res.getBody());
System.debug('Status ' + res.getStatus());
System.debug('Status code ' + res.getStatusCode());

results in:

15:00:19.37 (660162883)|USER_DEBUG|[8]|DEBUG|Body {"access_token":"xyz","instance_url":"https://xxx.my.salesforce.com","id":"https://login.salesforce.com/id/xx/xx","token_type":"Bearer","issued_at":"1493838019636","signature":"xx"}

15:00:19.37 (660248503)|USER_DEBUG|[9]|DEBUG|Status OK 15:00:19.37

(660399942)|USER_DEBUG|[10]|DEBUG|Status code 200

Digging Deeper into OAuth 2.0 on Force.com

An autonomous client can obtain an access token by simply providing username, password and (depending on configuration) security token in an access token request. Again the request is POSTed (1) to https://login.salesforce.com/services/oauth2/token, but the payload now has the form

grant_type=password&client_id=&client_secret=&username=&password=

The following parameters are required:

  • grant_type Set this to password.
  • client_id Your application's client identifier.
  • client_secret Your application's client secret. username The API user's Salesforce.com
  • username, of the form user@example.com.
  • password The API user's Salesforce.com password. If the client's IP address has not been whitelisted in your org, you must concatenate the security token with the password.