I am developing the serverless application with AWS Cognito, DynamoDB and Lambda.
I need some user-friendly ids for URL.
Is it possible to generate a number only ids with Cognito User Pool? If not what is the best way to generate it manually in lambda?
Thanks in advance.
No, Cognito only generates UUID format ID, you can get the user ID from JWT, no need put it in the URL.
If you insist on the numbers user ID, you could create a mapping table in the DynamoDB or RDS.
Related
I'm using AWS Cognito for user authentication/authorization and I'm wondering whether I need a User entity/model if Cognito stores all user data? And if the answer is no, what is the proper way to model relations for other entities? Should I use the Cognito ID?
summery
I'm gonna implement AWS Lambda Authorizer by Cognito.
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
But I'm not sure how to limit the access to api/lambda based on user.
For example,
Cognito user pool has two users: user-1, user-2
And there are two AWS Lambda Function for API : lambda-1, lambda-2
In this senario, I want user-1 to access only to lambda-1 and user-2 to lambda-2
please give me the solution to achieve it.
regards,
If you want fine-grained control, you're better of using a lambda authorizer. This would still allow you to do authentication using Cognito.
In your Lambda function, you can return an IAM policy based on the user that is authenticated and restrict the access to only the API paths that you want them to access. You can then simply put both lambdas behind different paths of your API.
I'm building an Angular 11 app with AWS Amplify as the backend which uses Appsync, dynamodb and a managed GraphQL API. I'm using the cognito user pools to authenticate. Authentication works neatly, but I am really confused about how to go about doing role-based authorization. I haven't done this using cognito before but I have a strategy in mind that should theoretically work out. I would like advice on if there is a better way to do this:-
Requirements:-
The app will be used by members of organisations that we are partnering with. Every member will be tied to an organisation. So organisations have their own table and so do members. Members of an organisation can only access content related to their organisation. So right after authentication, the client app has to get the id of the organisation the current user belongs to and also the role they play in that organisation to show/hide UI resources and filter data. Which UI resources they can access depends on the role they play in that organisation and of course the data they see there has to be restricted to what is related to their organisation.
This is a controlled beta release of our application, so Cognito user pools uses email and password to login. No other login option is provided for the sake of keeping things simple. User sign up is not possible. Only admins can add new users for now.
How I plan to do this:-
Cognito API is integrated to the client and the admin will add the
new members from the client UI and the client will add them to the
cognito user pool via the Cognito API
While adding the new members, the admin will specify which
organisation they belong to and what role they play in it. But the
organisation and role are not details that are stored within the
user pools. There is a separate dynamodb table called "members"
which stores these information because these can change frequently
and need to be flexible.
Additions made to the Cognito user pool trigger a lambda function
that automatically syncronizes the "members" table in the amplify
backend in a dynamoDB table with the new additions to the user pool.
So when the admin adds a new user from the client UI, they
fill out a form with the email ID, name, organisation and role of
the new user, and the client UI will create that user with the name
and email ID in the user pool via the cognito API. Once that request
returns the user's ID (remember it will also trigger the creation of
a record in the member's table via the lambda funciton), we create a
mutation to the member's table adding the organisation and the role to the user's record in the member table.
Cognito user pool only has the email ID, name and user ID and
nothing else, all other information is stored in the members table,
which also has the ID, and name (for human reference) but not the
Email ID. We will not be holding the same information in
these two tables to avoid redundancy.
Updates to the email ID can be made by individual users via the
client app which will do it in the cognito user pool via the cognito
API. And no updates need to be made to the member table after email
update since the member table doesn't have the email ID. All other
member details can be made to the members table via the client app.
When the user logs in, as soon as the cognito UI authenticates the
user and sends over the email ID and user id, we fetch the member
details from the member table using the user ID and get details such as their name,
organisation they belong to and their role. And using the
information on their role, we can restrict UI resources using flags
in the UI Code. To achieve this, there will be a separate table that
will let the admin user modify access to the UI resources for each
role. So we'll need to fetch the role and the associated UI tags
right after authentication as well.
And as for how data is filtered as per the organisation, I am not
sure yet, but I would like to use an authorizer that will be
specified using a function in the graphql schema itself, that will
get the organisation ID with each request and use that to filter the
data before returning to the client.
Not sure if this process is solid, but this is what I was able to fathom. Please let me know if I am doing this in a sensible way or if there are better ways to achieve what I am doing.
We are building a number of microservices using API Gateway+lambda+DynamoDB. We need to secure these APIs using Cognito which we are using for user management. We will have a user pool and two groups with a different IAM role attached to each group. The need is users in one group should not be able to access all services and so the users in other group.
Any suggestions, how we can implement this?
The issue is ID token generated by Cognito is not validated by API gateway to check what level of access user has. All it checks is if Cognito ID token is valid or not.
You can use API Gateway custom authorizers to validate policies attached to each group.
From AWS Documentation:
You can use groups in a user pool to control permission with Amazon API Gateway. The groups that a user is a member of are included in the ID token provided by a user pool when a user signs in. You can submit those ID tokens with requests to Amazon API Gateway, use a custom authorizer Lambda function to verify the token, and then inspect which groups a user belongs to.
Additional references to implement:
https://aws.amazon.com/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/
https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/
I have created my Amazon Cognito user pool and added few users. Added custom attributes in Cognito to differentiate between normal user and admin user. Exposed a REST API (for only admin users) to get the profile information of the given user using API Gateway and Lambda Engine to access my RDS DB instance to get few fields for that user from my DB.
I want to access the Cognito user profile information with the given username/subId from Lambda Engine / API Gateway.
I know with the given ID Token in API Gateway we can access the user profile details. But as a admin user I need to access details of other users with the given username from API Gateway or Lambda.
Kindly share, if you know how to get the user profile information from Cognito.
You are not mentioning which technology you are using to execute your Lambda functions.
Depending on SDK you will get an context object containing lots of information or you can read out the environment variables.
E.g. for Java the Lambda function gets a context object.
You could retrieve the identity from that one using:
context.getIdentity()
Update:
For Python it basically works the same way.
There is a context object as well. You can access it using context.identity.