Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Salesforce by (11.9k points)

I am new to SalesForce and am working through getting up to speed with the basics as we will be beginning a large integration project next week. For at least part of our integration, we will need to access the SalesForce Rest API. To that end, another gentleman on my team and I have done some basic prototyping of calls using Postman with good success, in particular around OAuth2 authentication. Our problem is that while everything seems to work fine in Postman, as soon as we switch to using C# to make the calls we begin getting an error instead of our auth token. The response is HTTP Status 400 Bad Request and the content of the response is

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

Here is a sample of some of the C# code we have tried:

using System;

using System.Collections.Generic;

using System.Net.Http;

using System.Web;

namespace SFTokenTest

{

    internal class Program

    {

        private const string LoginUrl = "https://test.salesforce.com/services/oauth2/token";

        private static void Main(string[] args)

        {

            FormUrlEncodedContent content = new FormUrlEncodedContent(new []

            {

            new KeyValuePair<string, string>("grant_type",HttpUtility.UrlEncode("password")),

            new KeyValuePair<string, string>("password",HttpUtility.UrlEncode("PASSWORD")),

            new KeyValuePair<string, string>("username", HttpUtility.UrlEncode("USERNAME")),

            new KeyValuePair<string, string>("client_id",HttpUtility.UrlEncode("CLIENTID")),

            new KeyValuePair<string, string>("client_secret",HttpUtility.UrlEncode("CLIENTSECRET"))

            });

            HttpResponseMessage response;

            using (HttpClient client = new HttpClient())

            {

                response = client.PostAsync(LoginUrl, content).Result;

            }

            Console.WriteLine(response.Content.ReadAsStringAsync().Result);

            Console.WriteLine(response.StatusCode);

            Console.ReadLine();

        }

    }

}

Note: this is one of many implementations we have tried including using HttpWebRequest and WebClient, all with the same result.

In addition to our own code we have tried pulling code from the GitHub repository developerforce/Force.com-Toolkit-for-NET which also presented the same issue.

So far we are two days into troubleshooting this with no luck and we have stumped our SalesForce consultant as to why it is not working. We tried resetting the Security Token this afternoon to no avail as well. I have looked through a number of articles online (including on StackOverflow) most of which point to the following issues:

  • Bad Credentials - We are using the same credentials successfully in Postman that we are attempting to use in our C# application(s) and we have tried re-coping and pasting them from the SalesForce UI and we have tried hand keying them into our code in case we were picking up invisible characters. (By credentials I am including username, password, client_id, and client secret.)
  • Bad or missing Content-Type header - we are definitely sending "application/x-www-form-urlencoded" which I have checked in each application a number of times (and have sniffed to verify it was actually being sent).
  • Unencoded Parameters - I have seen this on a number of StackOverflow threads and have verified that we are encoding the parameters we are sending I the request body.

It seems there is something that Postman is doing that we are not in our requests, but I cannot seem to pinpoint what it is. We even captured requests from both Postman and one of our clients and diffed them and they came back as identical.

Any help would be greatly appreciated.

1 Answer

0 votes
by (32.1k points)
edited by

Try adding a single ServicePointManager line.

For a console application like yours, I tried testing the following code on .net 4.5.2:

 string LoginUrl = "https://login.salesforce.com/services/oauth2/token";

        //the line below enables TLS1.1 and TLS1.2

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        FormUrlEncodedContent content = new FormUrlEncodedContent(new[]

        {

        new KeyValuePair<string, string>("grant_type", "password"),

        new KeyValuePair<string, string>("client_id","CLIENTID"),

        new KeyValuePair<string, string>("client_secret","CLIENTSECRET"),

        new KeyValuePair<string, string>("password","PASSWORD + SECURITYTOKEN"),

        new KeyValuePair<string, string>("username", "USERNAME")

        });

        HttpResponseMessage response;

        using (HttpClient client = new HttpClient())

        {

            response = client.PostAsync(LoginUrl, content).Result;

        }

        Console.WriteLine(response.Content.ReadAsStringAsync().Result);

        Console.WriteLine(response.StatusCode);

        Console.ReadLine();

I hope this works for you.

Are you willing to pursue a career in Salesforce, here's an opportunity for you Salesforce certification provided by intellipaat!

Related questions

+1 vote
1 answer
0 votes
1 answer

Browse Categories

...