Reputation: 16239
I'm using azure function with below code - everything is working fine when i run azure fucntion locally but after deployment i'm getting below error
{"error":"invalid_grant","error_description":"authentication failure"}
Function code -
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "tokenURL");
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("grant_type", "password"));
keyValues.Add(new KeyValuePair<string, string>("client_id", "clientID"));
keyValues.Add(new KeyValuePair<string, string>("client_secret", "clientSecret"));
keyValues.Add(new KeyValuePair<string, string>("username", "userName"));
keyValues.Add(new KeyValuePair<string, string>("password", "password"));
request.Content = new FormUrlEncodedContent(keyValues);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.SendAsync(request);
string respContent = await response.Content.ReadAsStringAsync();
var oauthResponse = JsonConvert.DeserializeObject<Dictionary<string, string>>(respContent);
string token = oauthResponse["access_token"];
Is there any other setting required from salesforce ?
Modify the Connected app: (Edit Policies) Relax IP restrictions
Permitted Usersto "All users may self-authorize"
Upvotes: 1
Views: 2187
Reputation: 971
Here is what we have in our Azure Functions that is working as expected. ISalesforceConfigSettings
is not from any library, its our own hand written interface whose implementation(s) read values from Environment variables.
/// <summary>
/// Gets the Salesforce access token given the client_id, secret, username and password.
/// </summary>
/// <param name="log">Tracewriter log</param>
/// <param name="_settings">ISalesforceConfigSettings _settings</param>
/// <returns>A Salesforce access token</returns>
private async string GetSalesforceAccessToken(TraceWriter log, ISalesforceConfigSettings _settings)
{
var httpClient = new HttpClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
// Create Request Body
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("client_id", _settings.SalesforceClientId),
new KeyValuePair<string, string>("client_secret", _settings.SalesforceClientSecret),
new KeyValuePair<string, string>("username", _settings.SalesforceUserName),
new KeyValuePair<string, string>("password", _settings.SalesforcePassword),
new KeyValuePair<string, string>("grant_type", _settings.SalesforceGrantType)
});
try
{
// Call to get access token
var loginResponse = await httpClient.PostAsync(_settings.SalesforceLoginUrl, formContent);
var loginResponseString = await loginResponse.Content.ReadAsStringAsync();
// Log Login Response
log.Info(loginResponseString);
// Extract Access Token
return JsonConvert
.DeserializeObject<SalesforceLoginResponse>(loginResponseString)
.AccessToken;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
Just in case if you're wondering what is SalesforceLoginResponse
class is...
using Newtonsoft.Json;
namespace Models.Salesforce
{
public class SalesforceLoginResponse
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
}
}
Upvotes: 2