I have been tasked with integrating our homegrown multi-client CRM with Salesforce.com. I am going to write a server-based service which will push information from each of our clients CRM datastores to Salesforce. I'd like to use the SFDC REST API, but could use the SOAP API if necessary.
I am struggling to understand the best security mechanism to use. As the solution will be server-based it is essential that no user interaction is required when connecting to SFDC. Our server needs to be able to establish a secure connection to SFDC without a user providing their login credentials.
So far I have experimented with the REST API, and OAuth2.0. I have setup a test SFDC account and configured our app within it, getting the consumer key, secret key and callback uri. This all works, and my callback page receives a security token. My callback page uses the supplied token as follows:
string rc = "";
try
{
string uri = "https://eu2.salesforce.com/services/data/v20.0/sobjects/";
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.Method = "GET";
req.Headers.Add("Authorization: Bearer " + token);
System.Net.WebResponse resp = req.GetResponse();
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
rc = "code=" + code + ", response=" + sr.ReadToEnd().Trim();
}
catch (Exception ex)
{
rc = "45435465 Token=" + token + ", err=" + ex.Message;
}
return rc;
Trouble is, every time I run this I receive a 401 (Unauthorised) reply from SFDC, even though I am passing the security token provided by SFDC.
Is the REST API the correct approach for 'unattended' access like this, and can anyone advise what I'm doing wrong in my code, or offer words of wisdom on how to get this working?
Many thanks.
Have you taken a look at Digging Deeper into OAuth 2.0 on Force.com?
If you read closely, you can see that the code
returned to the callback
page must then be used to obtain an access_token
. For example, the user will be redirected to your page like this:
https://app.example.com/oauth_callback?code=aWekysIEeqM9PiThEfm0Cnr6MoLIfwWyRJcqOqHdF8f9INokharAS09ia7UNP6RiVScerfhc4w%3D%3D
You must then make an HTTP POST to the token service here:
https://login.salesforce.com/services/oauth2/token
With the following url-encoded data (line breaks added for readability):
code=aWekysIEeqM9PiThEfm0Cnr6MoLIfwWyRJcqOqHdF8f9INokharAS09ia7UNP6RiVScerfhc4w==
&grant_type=authorization_code
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&redirect_uri=<your_redirect_uri>
The Salesforce token server will return with some JSON data as follows:
{
"id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
"issued_at":"1296458209517",
"refresh_token":"5Aep862eWO5D.7wJBuW5aaARbbxQ8hssCnY1dw3qi59o1du7ob.lp23ba_3jMRnbFNT5R8X2GUKNA==",
"instance_url":"https://na1.salesforce.com",
"signature":"0/1Ldval/TIPf2tTgTKUAxRy44VwEJ7ffsFLMWFcNoA=",
"access_token":"00D50000000IZ3Z!AQ0AQDpEDKYsn7ioKug2aSmgCjgrPjG9eRLza8jXWoW7uA90V39rvQaIy1FGxjFHN1ZtusBGljncdEi8eRiuit1QdQ1Z2KSV"
}
The returned access_token
can be used to authorize requests to the REST API. When it expires a new one can be obtained using the refresh_token
.
Supposedly, the refresh_token
is long lived and will allow you to get another access_token
for as long as the user has granted your application access. So, store it somewhere safe.
With regards to which API to use, I have implemented several "unattended" integrations using the SOAP API, so I know that it can work in that scenario. From a security standpoint, the downside of doing this it is that you have to securely store credentials. However, you will have to be able to decrypt them in order to get a sessionid. Because of this, they cannot be stored as securely as if they were hashed using 1-way encryption.
With the REST API, you only need to store the refresh_token
. If compromised, the attacker would have a lot less to gain from obtaining these vs a database full of credentials. Given that point, if I was to start from scratch today I would probably give the REST API a shot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With