I am developing an app with cognito for authentication and user management in a multi tenant application.
And the app provide a different app per client. Meaning one client will have its own cognito user pool and they get their own domain to login.
So the problem i anticipate in the future is we could reach more than a 1000 clients and the AWS cognitio limit of 1000 will be reached.
In this case the only way i can think of handling this is to create a new AWS account and getting more user pools from that account.
But i dont want to have to manage multiple AWS accounts in the future. I dont think we should use the same user pool for maintaining multiple clients because since each client gets their own app.
Not sure what is the best way to handle this.
Looks like the only way to do it would be to use a shared user pool among organizations.
And for each organization i need to create a different app client in cognito and make it work in that way.
And for the problem of users in one organization being able login in into other organization's app, due to the shared pool. I will have to create a validation layer before login in the application to to make sure that the username/email has the access to that organization or not.
Related
I'm trying to understand the relationship between Cognito user pools, and external identity providers via SAML.
What I have at the moment
I have ReactJS application which uses the Amplify library, backed by AWS Cognito. The application is multi-tenanted, and users from different tenants belong in the same user pool. They are separated by their group, and a custom attribute. I use CloudFormation and serverless framework to deploy my stack.
Currently, I have custom login forms, which communicate with the Amplify library to log in the user.
The goal
In addition to giving clients the option to make their own accounts on my platform, I want to provide an option to authenticate via SAML from an external identity provider. The goal is to allow each client to log the web-application using their own Single Sign On.
My prior research
I've seen AWS's example on how to actually deploy a user pool supporting SAML.
I've read Azure's guide on integrating with Cognito.
I have an understanding of the SAML authentication flow.
The question
Is it possible to attach each of these external identity providers to the same user pool, or will I have to deploy a new user pool for each new client I want to onboard?
Thank you very much
Yes, it is possible to add multiple external IDPs to a user pool.
But, there is upper limit of 1000 Identity providers per user pool. So you can add up to 1000 customers. And if you are go with user pool per customer, then there is limit of 10 000 user pools per AWS account.
So we can consider those limits when you are choosing an option.
One other option is to support login with IDPs like Google, Microsoft and etc. So companies(customers) who use them as their IDPs, can rely on that, without specifically configuring SSO. (You can group the users based on the domain).
I am currently using AWS Cognito and it's hosted UI to manage user login. All my users sit in a single pool, which has a number of different app clients registered. Our users are grouped into different organisations and for the most part a single user (or email address) is only associated with a single organisation, so this setup works very well. A small subset of users are associated to multiple organisations. Associated to a particular organisation is managed by a backend service rather than using Cognito attributes and/or groups.
We are already using the pre token generation Lambda trigger to inject claims into our tokens to denote which organisation a user belongs to which is then used downstream in our backend services to control which database is hit when a user makes an API request (we use single tenant databases).
I need to design a mechanism that will allow the users who belong to multiple organisations to select which organisation they want to login as (ie select which tenant they want to use for that session) at auth time. I know this will be impossible to do with the Hosted Cognito UI but I'm wondering if this is something that can be done with AWS Amplify along with a custom login app and using custom auth challenges. The flow would be something like this:
Username/password provided
Custom auth challenge lambda fires which detects whether the user has a 1-1 relationship to a single organisation (in which case we can log them straight in) or a 1-many relationship to multiple orgs.
In the latter case above, the auth challenge returns a collection of organisations that a user is allowed to log in to back to the app which displays them in a picker control (drop down or similar)
User selects their tenant and this information is sent to the auth challenge response and the login continues.
A key step after this would be ensuring that the custom challenge responses make it through to the pre token generation Lambda function so it knows which organisation the user is logging into.
I'm a backend developer and have had no exposure to Amplify at all, I just need to know if this is theoretically possible before I invest too much time into it.
Can anybody with Amplify experience confirm if what I describe would be possible using Amplify and a custom auth React app?
Thanks
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.
I am trying to authenticate users via AWS Cognito/IAM services from my webapp. I have implemented Facebook and LinkedIn login and I'm wondering how I could use AWS to implement username+password login via my UI. Is there a way for me to set it up so that all I have to do is drop in button for username+password login on my view and that will authenticate users and redirect back to my backend service (similar to Facebook/LinkedIn) and where I can put in an endpoint URL?
Do let me know If I need to be clearer.
Edit1: I have already tried using Developer Authenticated Workflow (enhanced workflow). I don't want to do the part where I create the User in my user pool by calling the AWS Cognito Identity API. I'd like AWS to do the user creation by itself. is this possible?
Edit2: Another alternative solution is to create a Lambda which does what I want. But this is similar to the code to do that (which is on my backend).
At the moment there is no complete solution for this. You have to either use newly introduced AWS Cognito User Pools or create your own one. I would also recommend to checkout the project https://github.com/danilop/LambdAuth which worth trying.
You can create AWS Cognito user pools and create the roles for authenticated and unauthenticated users and assign some policies for both roles. Once you have created the user pool you will necessary code to use in your web or mobile application. Refer How to setup Cognito user pools.
So since parse is shutting down we are moving our website / mobile app that we've been developing to AWS. We are primarily going to use the following services:
SNS, SES, Dynamo, S3, Lambda.
Now I am still a bit confused on:
what cognito is used for? Do we really need cognito to authenticate users and use DynamoDB, S3, SNS ? Or can we just use specific APIs for each of these services and connect directly (using Js SDK)?
If we do have to use cognito how do we save local data i.e logged in user/ identity? is that what cognito sync is for or do we have to use cookies ?
In summary why do I need cognito when I can directly connect to DynamoDB using the JavaScript SDK?!
Thank you in Advance.
Amazon Cognito can be decomposed in two sub-services: Amazon Cognito Identity and Amazon Cognito Sync.
Think of the former as an authentication service and a credentials provider. The latter is just a service to store user data and keep it synchronized between multiple devices.
What is the purpose of Amazon Cognito Identity?
Suppose that you have a table in DynamoDB. Let's say that you have a web application that will store an item on that table.
You can create an user in IAM, embed the credential information on the web application, and then put the item on the table using the AWS SDK.
There are three things going on here:
The credentials are embedded in the application
The credentials do not expire.
Every user in your application has the same access rights on your table
This may be fine for some applications, but Amazon Cognito Identity offers a solution to these common problems.
Let me explain Cognito Identity's workflow:
An user registers an account on your application, sending all the information (username, password, other data...) to your server.
The server stores the user in some back-end database (it could be a DynamoDB table) and creates a new identity on the Cognito service. This identity is then mapped to this user.
The user can now login into your application. The user logins and sends username and password to your server. (This process could be done automatically after account registration)
The server checks the username and password against your back-end database. If everything is right, then the server makes a request to Amazon Cognito for a temporary access token.
The web application receives the token and makes a request to Amazon Cognito (using that access token) to get the user credentials. These credentials are basically a temporary IAM user that was created specifically for this user. It will have an expiration (usually an hour).
The web application uses these credentials to make operations on AWS, such as putting an item on a DynamoDB table, or calling a Lambda.
When the credentials expire, the user must re-login into the application. This might be done automatically or not, depending on your application's requirements.
On the Amazon Cognito dashboard, you can configure roles and policies for your "identities" (an user in Cognito). This way you can specify which services it can access. It even allows you to create access roles for your users (Admin users may be able to access some services that normal users should not).
I should also note that Amazon Cognito can be easily adapted to support Facebook / Google+ / Amazon accounts, which will be mapped to the same identity, so the user can login via multiple sources.
What is the purpose of Amazon Cognito Sync?
Consider it like a DynamoDB table where you store information for a specific user. These information is shared between multiple devices and is always synchronized. This means that when a web application updates an user value, then the mobile application will automatically reflect this change.
There is a limit on how much user data you can store (I don't remember now), so it's not something you would use to persist information (such as an user password), but rather a mean to share information.