Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Security Approach for Integrating Salesforce.com with .NET Server C#

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.

like image 446
whatdoesitallmean Avatar asked Nov 13 '22 01:11

whatdoesitallmean


1 Answers

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.

like image 162
dana Avatar answered Nov 15 '22 12:11

dana