4

Goal:

I am trying to automatically link federated user accounts (Google) to a Cognito account with matching email addresses in the PreSignUp_ExternalProvider Cognito trigger.

Approach:

  • I followed most of the logic in this thread to response to the PreSignUp_ExternalProvider trigger, using client.admin_link_provider_for_user to link identities.
  • I am using an implicit grant flow and sending federated login users to: https://${userpoolData.AppWebDomain}/oauth2/authorize?response_type=token&client_id=${userpoolData.ClientId}&identity_provider=Google.

Expected Behavior:

I expect the outcome below (which includes known bugs/problems):

  • I use client.admin_link_provider_for_user to link the two accounts together
  • I end up with two user accounts: the original Cognito account and a new Google_<someId> in my user pool. My original Cognito account has attached Google identity info now, and my new federated account will redirect to my original
  • The auth flow will fail during the first sign-in with the username already found, but I can catch this and restart the auth flow.
  • A restarted auth flow should log me in successfully with an #access_token as the destination Cognito account

Problem:

No matter how many times I try to log in with the federated account after the first expected error, I get the following response when it calls back to my server: ${myServer}/idp#error_description=Internal+server+error.+&error=server_error.

Something that works, but is it supposed to be this way?

I can raise an exception in my Lambda trigger immediately after creating the link between the two accounts, which will successfully add identity info to my original user but interrupt the rest of the flow and not create the second Google_<someId> Cognito account.

client.admin_link_provider_for_user(
    ... my args
)
raise Exception("Preventing creation of duplicate account " + event['userName'])

Once I catch this exception and restart the auth flow, I am able to log in perfectly via federated auth as my original user.

This does not feel like a sustainable or intended pattern. How can I log in successfully without resorting to interrupting Cognito's intended behavior?

Serena Li
  • 41
  • 1
  • Did you maybe find a better solution than raising an exception in the lambda function? I have the same issue and I can't find anything. From the looks of it, I would say that Cognito doesn't know how to handle the returned `PreSignUp_ExternalProvider` event – Josip Kolarić Oct 25 '21 at 05:32
  • Sadly, I haven't yet found a better solution than raising the exception, but I have also not returned to this issue in a while. I would love to hear of other solutions if you or anyone else does come across one! – Serena Li Nov 01 '21 at 21:10
  • 1
    I'm facing the same issue at the moment with duplicated accounts being created despite admin_link_provider_for_user. Of course, I'm also using the pre-sign-up trigger lambda. This is what I observed. 1. Both links to the accounts in the Cognito console lead to one account (originally created). 2. When trying to manually disable/delete one of the accounts, Cognito always disables/deletes the original one. 3. When trying to process EXACTLY THE SAME event using a lambda tester, it passes through without a duplicate account created. It looks like a Cognito bug. – pbajsarowicz Jul 27 '22 at 09:45

1 Answers1

0

I was facing exactly the same issue. I have found the solution for my "Internal server error" issue on AdminLinkProviderForUser documentation, which says in a !Important box:

"All attributes in the DestinationUser profile must be mutable. If you have assigned the user any immutable custom attributes, the operation won't succeed."

After recreating my user pool having all my custom attributes as mutable, it worked.

PS: But it is still throwing "Already found an entry for username" error in the first sign-in, which I think is a Cognito core issue.

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Thank you for providing this answer! Unfortunately, there are no immutable custom attributes in the pools we are using, so we weren't able to try this solution. – Serena Li Apr 20 '22 at 17:05