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.
Related
For my custom application, i wanted to have user login handled by AWS, basically i wanted the IAM user login functionality and call back to application on successful login. Like the integrations with "Sign in with Google".
I do understand the AWS Cognito does this, but i wanted to have MFA with this user using a hardware key which is not supported by Cognito as my understanding.
Hardware key MFA is possible with IAM users, so if i can create a app which allows the IAM user to login on AWS and redirect back to my app with a callback or token then it will be good, any thoughts?
An IAM user/role is meant to log into AWS Management Console and when using the AWS SDK when creating Service clients. You use the credentials of an IAM user.
If you are not familiar with using an IAM user with the SDK, see this topic:
Get started with the AWS SDK for Java 2.x
What you are describing is a use case for Cognito and users defined within user pools. For example, you can protect your web apps by requiring a user to login with a user defined in a user pool using a login form such as:
Background
I am using the Amplify Framework(javascript) for Register/Login in my frontend website.
Register
Auth.signUp({
username,
password,
attributes: {
email: email
}
})
Login
Auth.signIn(payload.username,payload.password)
Every time user login, the cognito id token will be stored in localStorage for accessing API in API Gateway.
This is my API Gateway api setting.
Every successfully logged-in user can call ALL api, for the current design.
Question
Now I want to do role-based permission control on calling the api, e.g. role banner_admin can only call /banner api, while role equipment_admin can only call /equipment api.
After some research, it seems Identity Pool is able to achieve this. But I don't want to change my Login Flow.
Can someone provide the fastest and convenient way to achieve the role-based permission control in my application? Is it possible to NOT use identity pool?
Yes, it's possible to do this without using Identity Pools service.
Actually, Identity Pools is not one to use for this purpose..
It's just exchanging the temporary credential to the authenticated or unauthenticated user to access your AWS resources..
You should use Groups supported by Cognito User Pool service for this purpose.
Once the user would be authenticated by Cognito, the claims he's get will include group information he belongs to(If you added the user to a specific group in User Pool).
You can handle the permission based on this group.
Upon the post confirmation Cognito event, You can trigger your lambda function, then there you can add the user to the corresponding user group in background.
I'm currently getting started with aws services. I'm trying to build an admin UI for managing a cognito user pool. E.g I want to have some cognito users to have admin rights for creating new users from the UI etc. I'm a bit confused by the docs on the different ways to integrate authentication in API gateway, Lambda and DynamoDB. Do I need a Identity Pool for that use case? Or just different User Pool roles?
Thank you in advance for any help.
To use AWS resources you do need identity pool. You should create user groups in your user pool and assign them different roles in IAM. After this, create an identity pool and select cognito identity under the authentication providers. Also make sure you select "Choose Role from token".
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 building an SPA with Django REST as the backend. Right now I am using the standard Django authentication system and User models.
I would like the JS running on the SPA to be able to insert messages into an AWS SQS (i.e. sendMessage).
AWS has these doc on calling sendMessage from JS in the browser.
They also provide these docs on how to authenticate the user. My thought right now is to use Amazon Cognito. From the FAQ:
Q: What if I register and authenticate my own users?
Amazon Cognito can integrate with your existing identity system. With
a simple API call you can retrieve a Cognito ID for your end users
based on your own unique identifier for your users. Once you have
retrieved the Cognito ID and OpenID Token Cognito provides, you can
use the Cognito client SDK to access AWS resources and synchronize
user data.
Am I correct that for this to work, I would need to:
Create an IAM user for each user in my system. Or do I just need one IAM role?
When the user logins in my site (Django backend), I would have my backend then make "a simple API call [to] retrieve a Cognito ID"
Send that Cognito ID when the user loads the SPA.
User the Cognito ID from the JS running in the browser to call sendMessage to the SQS queue
Am I missing something here? Is there someway to remove the Django User backend and just user IAM Users so that I can avoid having to keep the two users lists in sync? I found this project but it does not seem to be maintained.
UPDATE:
It seems that there might be an alternative method of doing this where I don't use Cognito at all but rather expose an endpoint that can sign requests, "Query Request Authentication". This Heroku page talks a little about building a signing service.
Is this in fact an alternative option and if so what are the pro/cons of these approaches?
Amazon Cognito does not require you to register IAM users, just the 2 IAM roles. A slight modification to what you would need to do:
Create an Amazon Cognito Identity pool, configure with your developer provider.
Update the IAM roles associated with your pool to allow access to the services you want (for instance SQS).
From your Django backend, call GetOpenIdTokenForDeveloperIdentity to get the OpenId Connect token and identity Id for this user, return this to your JS application.
Configure your CognitoCredentials in the JS SDK. In the logins map, use the key cognito-identity.amazonaws.com and the value as the token returned from your Django backend.
Use the JS SDK to call SQS or any other services you wish from your application.
While using pre-signed URLs for SQS can work, using Cognito with the JS SDK will allow you to leverage other services supported by the SDK (DynamoDB, SNS, S3, etc).