How to get non-validated user attributes from AWS Cognito - amazon-web-services

I need to get some user attributes from non-validated users on AWS Cognito
My use case is the following:
An user sign up in the app, however he does not submit the validation code immediately
When he tries to sign in in the app, he is prompted once again to submit the code he has received in his e-mail
But then I cannot register this user in the database, because I donĀ“t have his data...Hopefully this was clear enough
I tried to research some resources online such as this AWS Cognito- get user information with ID and this one AWS Cognito: get user attributes of any unauthenticated user
However I am concerned about security of the user, regarding the GDPR... As I would be exposing an unprotected endpoint with access to some sensitive data...
Does any of you guys know how could I address such issue without violating any GDPR rule?
Is there any cognito method that returns the user data for non validated users when they try to sign In?

Related

Add custom attribute to user created in AWS Cognito console

I have an app with AWS Cognito auth implemented using Amplify. I do not want users to be able to sign up, instead the admin will sign up users via the AWS Cognito user pool console, by creating a new user.
I have created a custom attribute for users for a AWS Cognito userpool. I want to assign a value to that attribute for a user either when creating the user or after the user is created.
I cannot see how to fill in any values for attributes for a user when creating a user in the AWS Coginto user pool console.
When opening a created user in the console, I do not see how to add values for attributes for that user.
I have probably missed something in the Docs, but can someone tell me how to add values for attributes (including custom ones) for a user created in the AWS Cognito userpool console.
This is very simple solution.
Cognito console doesn't allow to input custom attributes or required any attributes by admin. This is norm because the user's info should be filled by himself.
So This is the workflow how this invitation auth flow would work in Cognito:
The admin creates new user in the console by inputting username, temp password only(He can chooses whether to send a verification email or not and auto-verified phone number or email upon creating)
Cognito will send the invitation email to the user with verification code or link codeParameter (If you would use custom message Lambda trigger trigger for this use case, you can customize the email message and put the username and temporary password along together).
At this point, you should include URL to redirect the user to your app's update password page.
In this update page, you should let him to input any required attributes himself and change password to complete the signup (In Cognito console, you should configure any attributes you need to get upon signup as required).
Here is the helpful link for you to review in order to understand how to complete the signup with Cognito by Amplify Lib:
https://docs.amplify.aws/lib/auth/manageusers/q/platform/js#complete-new-password
Cheers

AWS Cognito - migrate users from external provider

I have a web application which uses Cognito to allow users to login. Cognito uses external provider (Okta). When user login first time user entry is created in user pool. I also have second application which has to use the same user pool, but because of specifics of this application I have to use email and password authentication.
I would like users to receive an email asking them to set (reset) their password when they first log in web app. What's a best way to achieve that?
As far as i know it's impossible to set password for EXTERNAL_PROVIDER users, but I can accept creating new (duplicating) users. But still I'd like to ask about best way to do this.
Instructions below are for migrating between cognito instances, but you might find them useful.
there is only one way to get this done is migration lambda trigger. In short:
create new cognito
create migration lambda
add this lambda as a trigger to login and/or forgotten passwords
point users at cognito (this might not be necessary in your instance)
upon login, Cognito will check locally and if user is not found, will use the trigger to check programmatically in another source.
If authentication is successful, old cognito will return object with all properties, incl passwords, which you can then insert into new cognito.
more info here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-migrate-user.html

AWS Cognito not prompting MFA on first login

We have an application using AWS Cognito (+ hosted web UI) where users are only created by administrators. MFA with SMS is required. This is our current flow for new users:
Admin creates a new user using AdminCreateUser of aws-sdk. Email, name and phone number are given.
A new account is created with FORCE_CHANGE_PASSWORD status. Username and a temporary password are sent to the user via email.
User signs in for the first time with the temporary password.
Cognito asks for a new password.
User sets their new password and proceeds to log in.
MFA code is sent to user via SMS. However, Cognito does not ask for the MFA code. User simply gets logged in. Account status is now CONFIRMED but phone_number_verified is not set.
However, the MFA challenge works fine starting from the second login. In other words, user's phone number only gets verified if they manage to log in for the second time. This means that a user who forgets their password after the initial login is unable to reset their password (as it requires a verified phone number).
Any idea why this is happening and what settings should I look into? I'm aware I can avoid the main problem by programmatically setting phone_number_verified as true, but I'd like to know why the MFA challenge fails on first login.
I've been really disappointed in the AWS hostsed auth UI. It's ugly and very limited. As you've discovered, for example, it doesn't handle MFA at all.
The best alternative I've found is to use the Authenticator Amplify UI component. It's possible to use Amplify UI without using the Amplify CLI or hosting your site on AWS, so it's pretty well a drop-in solution. Authenticator handles setting up software TOTP tokens and the TOTP challenge as needed. I haven't used it for SMS, but this page implies it's supported.
You can learn how to use Amplify UI components standalone (without the CLI and AWS hosting) in this StackOverflow answer.

AWS Cognito - help understanding authenticated vs. unauthenticated access

I don't understand auth. vs. unauth. user access within AWS Cognito. While learning about Cognito I came across several articles on the Internet and questions here within Stackoverflow concerning this and I'm just not grasping the concept.
I'm gathering that a simple use case for unauth. user access within Cognito is when we have users who need to access some AWS resource(s) who have an account but aren't "logged-in." But how is this possible? In other to get an access token, wouldn't you need a valid username and password? If by unauth. we mean a user who has a valid access token but can't access some resources [based on some user pool parameter], I suppose that makes sense, but I don't understand how Cognito works in this regard.
I've searched for hours on this w/o grasping this concept and I really just need a little help from the community if anyone would be willing to share.
UPDATE: What's confusing to me is that "unauth." is a non-logged in user already, no? Why do I have to or want to get an access-token for a non-logged in user? What is the purpose of this?
Something that is confusing when starting out with AWS Cognito, is that it is actually two services. Cognito User Pools is a user store that authenticates users and Cognito Identity Pools authorizes users.
Unauth:
When referring to a unauthenticated flow, you're skipping the authentication process and really just authorizing with an identity pool. To do this in code, you setup a credentials provider, and make a call to GetID. This generates an identityID in the identity pool and retrieves authorization tokens that give access based on the IAM role for unauthenticated users. Example here
Auth:
Now for the authenticated flow, before you authorize with the identity pool, you have to have authentication tokens. These can be retrieved by authenticating with a third party (Facebook for example), or with a Cognito User Pool. You authenticate with those services by providing a username/email and a password. The tokens delivered by those services can then be "passed" to a credentials provider. When done this way, authorizing with the identity pool will return access tokens that give access based on the IAM role for authenticated users. In addition, a user can "log out" and later "log back in" and they will be able to receive the same identity ID that was generated for them the first time they authorized with the identity pool.
I hope that all makes sense. I'll give an example of why you may combine the two
Example
Let's say we're building a web platform that lists events around our city. This platform needs to:
Store events in a database
Allow city organizers to add events to the database
Allow residents to view the events
We wouldn't want the residents to have to login to view publicly listed events, so when they visit the event's page of our website, unknown to them, they actually authorize with an identity pool. Thus they are provided unauth IAM role access to make a GET API call to our database, to retrieve the events.
Of course, we don't want just anyone adding events to the database. So for city organizers, there is a login form. This login form takes a username and password to authenticate them with a user pool. The user pool tokens are then used to authorize with the identity pool, giving them auth IAM role access to make a POST call to our API, allowing them to add events to our database.

AWS cognito: sign in with usernam/password OR facebook

I want to integrate a pretty standard functionality: give option to user (mobile and web) to either login with email/password or with facebook (google) account with RBAC (different users may have different roles, like users, moderators, admins, creators, etc). Here is basically what I want from sign in:
I went through a number of AWS tutorials and other materials. I got some grasp on how to implement it, but I still don't have a full picture. Hope someone can help me here.
Here is my current understanding (please correct me where I'm wrong).
1) For the email/password signup/signin I use a User Pool. When user signs-in I call authenticateUser (I'm using JS SDK):
cognitoUser.authenticateUser(authenticationDetails, {
..
})
where onSuccess
I store identity, access and refresh tokens, so, user
doesn't have to enter his credentials every time
Because users will be accessing AWS servicess (e.g. S3) I exchange idToken to AWS credentials
Store AWS creds in LocalStore for further use, when access resources
2) For the facebook sign-in I use Federated Identity
get a facebook access token
with fb token get a cognito identity
exchange a cognito identity to AWS creds and store those in LocalStore
Questions:
Q1. Is it valid and fairly complete logic for sign-up/sign-in? Did I miss anything?
Q2. How should I store facebook users? Can I do it in User Pools? I have impression that it's not possible, but that means I have 2 different user directories: one in UserPool and another one in another place (lets say in DynamoDB)
Q3. If I have to store users in different places (UserPool and DynamoDB) that means I have 2 users for essentially one user, who first registered with email/password and then decided to use facebook - this is inconvenience for both me as app admin and user. How to deal with this situation?
Q4. How to manage groups for users, who signed-in with facebook token (like users, moderators, admins, creators, etc)?
Q5. How should I restrict access to resources other than AWS for facebook signed-in users?
Q6. Any working example for this?
Thanks!
We added support for Federation through Facebook, Google and LoginWithAmazon for User Pools. This will create a user in user pool when a user logs in with federation. You can also capture the attributes from the identity provider using the attribute mapping feature.
Also if you use the app integration feature, Amazon Cognito User Pools wil generate a sign-in page like this for you.
Steps to SignIn/SignUp with a social provider through Amazon Cognito Console:
Configure a domain for your user pool like .auth..amazoncognito.com
Add any social provider and configure attribute mapping.
Enable the provider on the App Client.
Configure the callback URI, OAuth response type and allowed scopes.
Access your hosted UI at https://.auth..amazoncognito.com/login?client_id=&response_type=&redirect_uri=
Click on the button to SignUp/SignIn with Facebook (or your provider).
Authenticate with the provider, you will be redirected to the callback URI with tokens/code.
Check the newly created user in Amazon Cognito console.
I'm human and may have missed something, but that sounds pretty good to me.
You can't store a federated identities login in user pools. Thing of user pools as another identity provider, just like Facebook is. Dynamo (or something else) would be the way to go.
If a user logged in with both, linking those logins, you might want to consider avoiding user pools attributes entirely and only using dynamo. With two logins linked, Cognito federated identities only requires one login token to proceed, but user pools requires it's login token to see/update attributes. The user would have to login with the user pool to touch those attributes, it'd get messy.
I don't know that this is supported out of the box, like it is with user pools. You might have to do this using your hypothetical user database described above.
You can also link your user pool to Cognito as a provider, much like you do for Facebook. That's how you exchange an id token for credentials.
No official example from the service, though I can't speak for others.