9

I have added the IP to SalesForce and tried appending the security token to the password and checked that the user's profile has API enabled but still no luck.

The user account can log in fine using a browser.

Can someone please explain what settings a user needs to be able to log in through the API? Or how to debug this further. I can see the failed login attempts on the web interface.

This is my code:

        var header = new SalesForceAPI.LoginScopeHeader { organizationId = "00D40000000XXXX" };
        var service = new SalesForceAPI.SoapClient();
        var result = service.login(header, "XXXX@XXX.com", "XXXX" );

The exception I get is: INVALID_LOGIN: Invalid username, password, security token; or user locked out.

Any help is greatly appreciated.

EDIT:

What is a self service user?

  • 1
    What reason does the failed login attempt in the user's login history specify on the web interface? – techtrekker Nov 7 '12 at 19:37
  • 2
    Did you append the security token to the password? – jordan.baucke Nov 7 '12 at 19:54
  • I think you have all the pieces you need. Have you tried regenerating the security token? – Paul Sasik Nov 7 '12 at 20:06
  • The Website notes the login attempt with status "Invalid Login". I regenerated the security token to get it in the first place but it shouldn't be required because the service calls are coming from a known IP. I wondered if there could be a weird profile think I was missing or that I needed to pass in the LoginScopeHeader – Max Nov 7 '12 at 23:01
  • Once you've whitelisted the IP for a profile adding the security token will cause an invalid login. Have you tried logging in with just the password? Or after removing the IP restriction? – Ralph Callaway Nov 8 '12 at 3:56
8

I imported the Partner v26 WSDL into a Visual Studio 2012 console application as a Web Service Reference (not a WCF service reference).

Then with a bit of painful cutting and pasting from the PDF I brought the C# example code in from the SOAP API developers guide pg 27 referenced by Jordan in his answer. It looks like their example is designed for use with the Enterprise WSDL as it has a Contact object in the querySample() method. So I hacked that section out to get it compiling.

I named the Web reference "SforceService", so the only other change I needed to make was to change the using Walkthrough.sforce; to using ConsoleApplication1.SforceService;.

I was able to run the sample code and establish a Salesforce session with a username and password (no security token as the IP had been trusted in the org).

Do you want me to try and zip up the console application project and share a link?


string username = "XXX@YYY.com";
string password = "password";
// Create a service object
SforceService binding = new SforceService();
// Timeout after a minute
binding.Timeout = 60000;
// Try logging in
LoginResult lr;
try
{
    lr = binding.login(username, password);
}
// ApiFault is a proxy stub generated from the WSDL contract when
// the web service was imported
catch (SoapException e)
{
    // Write the fault code to the console
    Console.WriteLine(e.Code);
    // Write the fault message to the console
    Console.WriteLine("An unexpected error has occurred: " + e.Message);
    // Write the stack trace to the console
    Console.WriteLine(e.StackTrace);
    // Return False to indicate that the login was not successful
    return false;
}
// Check if the password has expired
if (lr.passwordExpired)
{
    Console.WriteLine("An error has occurred. Your password has expired.");
    return false;
}
/** Once the client application has logged in successfully, it will use
* the results of the login call to reset the endpoint of the service
* to the virtual server instance that is servicing your organization
*/
// Save old authentication end point URL
String authEndPoint = binding.Url;
// Set returned service endpoint URL
binding.Url = lr.serverUrl;
/** The sample client application now has an instance of the SforceService
 * that is pointing to the correct endpoint. Next, the sample client
 * application sets a persistent SOAP header (to be included on all
 * subsequent calls that are made with SforceService) that contains the
 * valid sessionId for our login credentials. To do this, the sample
 * client application creates a new SessionHeader object and persist it to
 * the SforceService. Add the session ID returned from the login to the
 * session header
 */
binding.SessionHeaderValue = new SessionHeader();
binding.SessionHeaderValue.sessionId = lr.sessionId;

Note that the LoginScopeHeader is not required. According to the linked documentation it:

Specifies your organization ID so that you can authenticate Self-Service users for your organization using the existing login().

| improve this answer | |
  • Thank you very much but I'm up and running now. Out of interest does your login method take 2 or 3 params? I'm using enterprise WSDL – Max Nov 8 '12 at 10:45
  • @Max Just two when using the partner WSDL. – Daniel Ballinger Dec 12 '12 at 22:58
  • This comment made me realize why I had such issues with it; WCF has a different, more annoying format. – sfdcfox Aug 2 '13 at 2:27
2

Use Wireshark or some other low-level network request program to debug your requests if you don't have an IDE to examine your requests. You should be able to get started and verify your on the right track using simple CURL requests from the command line.

The SOAP API developers guide has easy quick start examples to get you going.

See page 27, it has C# example code, copy and paste it, and confirm it works.

| improve this answer | |
  • 1
    The documentation seems completely inaccurate. For example there is no mention of creating a login scope header which is in the WSDL. – Max Nov 7 '12 at 22:53
  • Where did you get the reference to the login scope header if it's not mentioned than you probably don't need it, if it is mentioned and not explained that's not good! – jordan.baucke Nov 7 '12 at 22:57
  • Also, you would recommend sending SOAP messages using CURL?? – Max Nov 7 '12 at 22:58
  • I said in my comment, it's in the WSDL. – Max Nov 7 '12 at 22:59
  • 1
    The code samples do not match up with the proxies that Visual Studio generates, preventing those code samples from being run. – Max Nov 7 '12 at 23:13
2

A lot of effort was put into the answers and comments given but none succinctly explain the problem and the solution.

LoginScopeHeader is only required for self-service users.

The following code is all that is required to login using Visual Studio generated proxies from the Enterprise WSDL.

    var service = new SalesForceAPI.SoapClient();
    var result = service.login(null, "XXXX@XXX.com", "XXXX" );

Unlike the documentation, my service will not compile without three arguments for the login method.

| improve this answer | |
1

Check your Login History for any issues. Also try to write some simple script which will check your credentials.

Example test script in perl:

#!/usr/bin/perl
# Usage $: PERL_LWP_SSL_VERIFY_HOSTNAME=0 ./sf-test-login.pl

use strict;
use warnings;
use lib 'lib';
use lib $ENV{HOME}.'/lib/perl5';
use REST::Client;
use JSON;
# use Data::Dump qw(dump);

##### Salesforce setup/login
my $grant_type = "password";
my $client_id = "CHANGE_THIS";
my $client_secret = "CHANGE_THIS";
my $username = "CHANGE_THIS";
my $password = "CHANGE_THIS";

my $json = JSON->new->allow_nonref;
my $client = REST::Client->new();

$client->setHost('https://emea.salesforce.com');
$client->addHeader('Content-Type', 'application/x-www-form-urlencoded');

my $login_body = "grant_type=$grant_type&client_id=$client_id&client_secret=$client_secret&username=$username&password=$password";

$client->POST('/services/oauth2/token', $login_body);
my $result = $client->responseContent();
my $json_result = $json->decode( $result );

print "Token is ", $json_result->{"access_token"}, $/;

See:

| improve this answer | |
0

Make sure your password does not have any special characters in it that are causing problems. This was my issue.

| improve this answer | |
0

Removing special characters from the password works. After updating your password, you must also reset and update your SECURITY_TOKEN.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.