1

Any Cognito User Pool gurus out there? I've been using Cognito for a while now but this one has me a bit stumped.

  • We allow users to sign up and sign in using social accounts like Facebook which are set up as Identity Providers in the User Pool.

  • Users need to complete a custom registration form before they can use the main app - we don't use the hosted UI for login or signup

  • One step of the custom registration process allows the user to indicate which social provider then want to use

  • This allows us to pull back the users email, first and last names from the social provider which is great - we use a cognito client and callback to do this currently

  • But in doing so, this provisions a user within the Userpool before the registration process is complete - in fact this makes sense- in order for Cognito to provide us the user info it needs to have called into the social providers /userinfo endpoint to populate the user data

  • So, the issue we now have is that whilst the user is half way through the registration process I have a confirmed user account - eg. before the user has completed the registration process

  • This is an issue because a user could sign into the the app using their social login without ever have completed the registration process

So as I see it I have two options:

  • PostConfirmation Lambda trigger which uses the cognito-idp SDK to disable the user just after it was confirmed
  • Don't use Cognito to obtain the user info like firstname, lastname, email, picture etc - however this would require us to write a solution for every current and future social provider which isn't something I'm keen on

Am I missing something obvious?

Thanks in advance!

BigJump
  • 15,561
  • 3
  • 31
  • 29
  • Just ran into a very simillar issue - I'd like to enforce phone number verification before I consider user coming from Google/Facebook as verified in Cognito. How did you manage to solve this? – blahblah Nov 16 '20 at 14:50
  • It’s been an ongoing challenge - but this approach seems to be working for me. https://github.com/aws-amplify/amplify-cli/issues/4427#issuecomment-718549881 – BigJump Nov 19 '20 at 19:48

2 Answers2

2

The simplest solution in the end for us was a Pre Token Generation Trigger in Cognito like this:

exports.handler = async (event) => {

  if(event.triggerSource==="TokenGeneration_HostedAuth") {

     //check db/api etc to see if we have a valid registration stored for user
     if(!hasCompletedRegistration) {

       //throw auth exception which we can catch on the frontend to inform user
       throw new Error("REGISTRATION_NOT_COMPLETE")
     }
  }

  return event

};

For username/password sign ins the TriggerSource will be TokenGeneration_Authentication

For federated/social sign ins the TriggerSource will be TokenGeneration_HostedAuth

BigJump
  • 15,561
  • 3
  • 31
  • 29
  • We've learnt a few things along the way though: * Social account merging - thanks to @Leon and see https://github.com/aws-amplify/amplify-cli/issues/4427#issuecomment-718549881 - pretty easy, but make sure to create the native username/password account first and link all social providers to that * Custom Auth Flow is not supported by the Hosted Auth which means that whether you are working with the hosted UI or the Amplify Auth.federatedSignIn you can't customize the auth flow for social sign ins. – BigJump Nov 21 '20 at 11:47
1

I would say PostConfirmation Lambda trigger is a good approach - however instead use adminDisableProviderForUser to disable the user from signing in with the specified external (SAML or social) identity provider

adminDisableProviderForUser

You can later call adminLinkProviderForUser to link the existing user account in the user pool to the external identity provider.

adminLinkProviderForUser

An alternative solution is to prevent the user from signing in if they have not fully completed the registration process via a Pre Authentication Lambda Trigger checking for a unique identifier with respect to your completed registration process

Leon Africa
  • 509
  • 6
  • 11
  • 1
    Thanks for this - I discovered that you can’t unlink a provider if the only account for the user is a provider account - it seems the solution is to create a native (email/password) account during PreSignUp and then linking the social provider when you are ready to do so as per https://github.com/aws-amplify/amplify-cli/issues/4427#issuecomment-718549881 – BigJump Nov 19 '20 at 19:51