8

Background: We've created a pseudo-single-sign-on integration between our external cloud program and our Salesforce environment, allowing our users to log in to our Lightning Community Site via a Visualforce page that uses Site methods to log the user in. Long story short, we built a custom API that our external program calls when a user is added to that program, and it automatically creates a Contact and Community User on their associated account in Salesforce, and then sets their password using System.setPassword().

Ultimate Problem: The password that we set after user creation does not work.

During some debug testing, we tried to do it directly through Execute Anonymous to see if there was a problem in our apex logic somewhere, the following code executes successfully, but the user is still not able to login with the password afterwards.

Id profId = [SELECT Id FROM Profile WHERE Name = 'Community Knowledge User' LIMIT 1].Id;
Account a = new Account(Name = 'Test5');
insert a;
Contact c = new Contact(AccountId = a.Id,
                       FirstName = 'Morgan',
                       LastName = 'Ma',
                       Email = '[email protected]',
                       Title__c = 'Administrator');
insert c;
User u = new User(ContactId = c.Id,
                  Alias = 'MSstA5',
                 FirstName = c.FirstName,
                 LastName = c.LastName,
                 Email = c.Email,
                 Username = c.Email,
                 ProfileId = profId,
                 EmailEncodingKey = 'ISO-8859-1',
                 LanguageLocaleKey = 'en_US',
                 LocaleSidKey = 'en_US',
                 TimeZoneSidKey = 'America/New_York');
insert u;
System.setPassword(u.Id, 'Welcome1*');

If we try to run System.setPassword again in execute anonymous to set their password to Welcome1* again, we receive the UNKNOWN_EXCEPTION: invalid repeated password error, indicating that the users password IS recognized as already being Welcome1*. However, the password does not work to log the user in either via our Visualforce page OR directly via the standard login page.

If we run System.setPassword and change it to Welcome2*, the user is suddenly able to login fine. We can then use System.setPassword to set it back to Welcome1*, which also works fine afterwards, but we cannot get the users password to work if the password was set in the same transaction after the user was inserted - even though Salesforce seems to acknowledge that it is the correct password (by nature of the invalid repeated password error).

I've found 2 similar posts

one suggests that you just need to wait a short time and eventually the password will work because it may be delayed: Setting new user passwords in Apex

However, we have waited for multiple hours now, and the issue persists.

Another post had a curious suggestion of doing a second query and return of the User object: Issue creating user and setting password

However, our code already does something similar, but this suggestion doesn't appear to have any merit or work in this context.

We'd like to avoid creating a future method specifically for the purpose of setting these users passwords, but are struggling to understand why Salesforce is recognizing the password as valid, but not letting the user login. Inspection of the user account shows them as active, not frozen, and the login history does post logs indicating Invalid password was provided, even though the password was set and acknowledged by System.setPassword as Welcome1*. We're concerned with creating a future method for this purpose because there are already future methods occurring in this transaction and we may encounter the future cannot call future issue.

Ultimate Questions: Is this a known issue/limitation within Salesforce? Is there something we are missing? Is there a flag or parameter that we need to set on the user to further 'activate' them that isn't being set during the initial creation or SetPassword call? Why does it work when done in a separate transaction but not when done in the same transaction after insert? It appears to be correct, but recognized as incorrect. The documentation doesn't mention this as a limitation.

5
  • I am sure you do have u.isActive = true. Also a thought here, if can you try re-querying the user as soon as you insert and then use the retrieved entity to set the password? Say something insert u; User newUser = [SOQL]; System.setPassword(newUser, <pwd>)
    – Jayant Das
    Commented May 23, 2018 at 16:08
  • Thanks for your suggestion - we tried this approach, but the results were the same. Commented Jun 8, 2018 at 14:44
  • @MorganMarchese did you ever find a solution to this?
    – Gunner1714
    Commented Nov 4, 2020 at 21:47
  • @Gunner1714 I don't know that we ever truly solved this. It seems like a bug in Salesforce (or an undocumented limitation). Since our users never know their password, the solution we came up with was to reset their password on the visualforce SSO controller prior to executing their login. This worked because it was a separate transaction. I still believe it's not possible to create a user and set their password in a single transaction, but you can likely achieve it with future, or Queuable Interface transaction chaining. Commented Nov 5, 2020 at 12:57
  • 1
    We ended up adding @Future to out apex class and if our users don't log in right away then we should be fine.
    – Gunner1714
    Commented Nov 9, 2020 at 18:27

0

You must log in to answer this question.

Browse other questions tagged .