My current project is in AWS, using Cognito and microservices with Lambda. We have designed the microservices using DDD and are in the process of implementing basic functionality.
However, there is a business need for users of the API to be able to be categorised into the client company that they work for, and only be able to access data for that client company as well as any role-based authentication we will have.
This isn't a full multi-tenant solution as every user will be working with the same website, but their account will have been associated with a particular client.
Everything I have read about doing something like this in AWS suggests using one user role or pool per client and associating users with it when they are created, however we do not want to do this, as the clients typically consist of 2-3 users and there are many clients. This would quickly become unmaintainable in terms of number of user pools.
I tried to think of ways around this issue using "conventional" means, such as adding a domain service into the architecture which was solely designed to add client data to each request by a particular user by calling into the user microservice, but this seems overly complex. I also considered changing the architecture to include basic user and role information in each microservice, but that seems messy.
My question is are there any officially supported ways to add data into an AWS Cognito profile programmatically, and in such a way that this could be changed through a front-end website by a client admin after the account has been created? Even if it's just a clientId field in the token.
If not, then what would anybody who has experienced a similar issue recommend as an alternative to the user pools suggestion.
Thank you.
EDIT:
I have also been investigating several ways to do this using attributes on Cognito profiles, as mentioned here. It seems like this is the way to do more or less what I'm trying to achieve, but I'd still like to hear about alternatives or advice.
The solution we will use for this issue will be to use custom attributes as part of the Cognito user set-up. We will have text fields for additional attributes or groups that the user belongs to.
The way this should be implemented can be found at the following links:
Managing SaaS Identity Through Custom Attributes and Amazon Cognito
Managing SaaS Users with Amazon Cognito
SaaS identity and isolation with Amazon Cognito (Example Guide)
SaaS Storage Strategies
With this data being automatically passed into each service as part of the Cognito credentials, we will be able to check that the user has the valid credentials for accessing data specific to each client.
Examples of how to work with Cognito in a NodeJS application (sometimes with Serverless) include:
https://serverless-stack.com/chapters/login-with-aws-cognito.html
https://serverless-stack.com/chapters/add-a-create-note-api.html#configure-the-api-endpoint
This seems to be most easily achieved by using the aws-amplify package, which is primarily designed for front-end authentication, but which can be used in NodeJS for back-end authentication as specified here.
Related
I would like to use Amazon cognito as a way to allow users to sign up to my app and validate api calls, so I don't have to handle user passwords or create a custom account recovery email system.
The problem is im not sure I understand how its supposed to work or what tools I am meant to use. Heres how I imagine it:
This way I could use cognito to identify users and authorize api calls.
But I am not sure if this is correct. For example I'm not sure if the frontend is supposed to refresh the tokens or the backend.
I am also not sure if I am meant to implement the code for exchanging and refreshing the token and logging out of users myself, but it seems that way since I can't find any tools that would do that for me.
I have found some libraries concerning aws cognito, but none of them mention exchanging or refreshing tokens:
https://www.npmjs.com/package/amazon-cognito-identity-js
https://www.npmjs.com/package/amazon-cognito-auth-js
https://www.npmjs.com/package/#aws-cdk/aws-cognito
I did find this library mentioned in the documentation that can be used to validate jwt id tokens on the backend.
https://github.com/awslabs/aws-jwt-verify
I am using userpools and no identity pools, since I don't grant users access to my aws resources.
So basically my question is, is my perception of the cognito workflow correct and if yes, how can I exchange the grant code for an id token and how can i use the refresh token to refresh the id token.
I've built an application which is connected with Amazon Cognito to take the sign in and sign-ups of users. Currently, application support three different subscriptions (Free, Basic, Premium). If the user signs in for basic Subscriptions, I want to give them least access to DynamoDB for download the parts of applications which is required to run the application service.
How to connect DynamoDB with Cognito directly
I am not sure, what's the best approach to follow this scenario?
(Please note- this is not a mobile-based application, so do not give suggestion to use AWS Amplify or relatable services)
When I was first learning about Cognito, I had made the same set of assumptions you are currently making. I knew that User Pools could act as my application's user directory, and Identity Pools would magically unlock all my authorization needs. I was mistaken :)
At the risk of oversimplifying, AWS Cognito exists to answer two questions:
Who are you? (authentication)
What can you do? (authorization)
Cognito addresses these concerns with two distinct offerings: User Pools (authentication) and Identity Pools (authorization).
At a high level, User Pools let you handle user registration, authentication, account recovery, and supports authentication with third-party identity providers like Facebook, Google, etc. Sounds like you might have this part figured out.
Cognito Identity Pools, on the other hand, provides a way to authorize users to use various AWS services. You can think of it as a vending machine for handing out AWS credentials. For example, if you needed to give your users access to upload a file to an S3 bucket or to invoke an endpoint in API Gateway, you could do so with an Identity Pool. You can even allow item-level access to DynamoDB based on an Amazon Cognito ID. However, this might not work the way you expect since your application users are probably not directly connecting to DynamoDB.
In most web/mobile applications, users are not connecting directly to DynamoDB. Instead, they are interacting with a web/mobile app that communicates to the back-end of your application via an API. That API would then communicate with DynamoDB. If your stack is in AWS, the path may look something like this:
Client (web/mobile app) <-> API Gateway <-> Lambda <-> DynamoDB
In this architecture, your users would authenticate via Cognito. Cognito would then authorize the user to make calls to API Gateway. API Gateway would execute your lambda, which would then interact with DynamoDB. The "user" of DynamoDB in this example is your Lambda, not the user of your application.
That last bit is important, so I'll repeat it: Unless your users are directly connecting to DynamoDB (not recommended), they are not the "user" operating on DynamoDb. Therefore, restricting DynamoDB access based on a user's Cognito ID is not going to be an option for you.
So, what can you do? Your application needs to provide the business logic around what effect your users can have on DynamoDB. Perhaps free users have read-only access to a specific partition, while premium users can modify the same partition. That logic has to be handled directly by you.
I know you said you weren't looking for Amplify suggestions since your application is not mobile-based. However, Amplify offers SDKs that aren't specific to mobile development. The folks at Serverless have made a fantastic tutorial on building a full-stack serverless web app, which includes a very readable chapter on serverless auth with Cognito. They use Amplify in a web app to integrate with Cognito, S3, and API Gateway. If that's something you are trying to do, I'd recommend checking it out.
I wanted to check we can use a custom node.js implementation as wrapper for exposing the API's for identity and user management using aws cognito.
We already have a bunch of API's (on ASP.NET identity) and would not want to change anything in the downstream systems. We would like keep the API signatures and just move the implementation to node.js server for identity and user management
The current examples on awslabs and the documentation is mainly targeted for using this under a web/mobile applications. Is there any guideline/sample if we can use this as an API wrapper.
Apologies if I'm misinterpreting the question, but are you just trying to use Cognito with node instead of on a web app? Are you asking about Cognito federated identities or Cognito user pools?
If federated identities, yes, that will be fine and you shouldn't have any issues. All of the APIs are available in the node SDK, and the general flow should be identical to any other non mobile flow.
If you're asking about user pools, it's a bit trickier. Authentication uses SRP to validate passwords, and the mobile/web SDKs do this for you. Outside of those, you'd have to implement it yourself, which is no fun at all. You could rip out the code that does it from any one of those SDKs (each are published on Github) to help with that. Alternatively, you could use admin no srp authentication, which carries the risk of sending the username/password over the wire but passes off the authentication to the Cognito server.
So I may be barking up the wrong tree here, but I have got the api manager working against rest services and can provision users through LDAP.
I can restrict access to certain services by role.
All good so far, however as many users will authenticate through a SPA (AngularJS) and the application will call multiple Rest Services, what I don't want users to have to do, is go to the store and subscribe to all relevant APIs, I would like the users from the LDAP server to be subscribed to all relevant services and have the roles they have limit access to the service.
Is there a way to have authentication done by just being in the identity store and authorization to be managed by the restrict by role setting.
Does this need scripting, is it a setting, or is it impossible?
Thanks in advance
Your requirement isn't supported OOTB in API Manager, still you can do it with little effort.
API Manager provides REST API to subscribe APIs. You can write a client which call the REST API onbehalf of the user and subscribe him.
Have a look on REST API
I'd like to run some stateless Java services on the Bitnami stack on AWS that will be consumed by apps... and of course to access these I'd need some type of authentication and authorization.
Previously with this type of architecture I've chucked an API gateway in front of them, to which the developer would subscribe. And AWS provides an API gateway, nice.
HOWEVER, while reading up on how to set this up on AWS I came across 'AWS Cognito' which is supposedly designed specifically for this same purpose.
So my question is are these two solutions comparable - are they doing the same thing?
And if-so, then what are the pros and cons of each, when would choose one over the other?
Basically because you are targeting the user level you should use Cognito; as it does provide you with authentication, reseting passwords for the user, and of course
signing up workflow. Moreover it provides user information to the admin, as well as two factor authentication, by using the user's mobile phone.
If you want to authorize the application to use an api then you use the API Gateaway.
The Cognito, is designed for user interaction it has an api for Java, JavaScript, iOS, and Android, so you can
implement the interaction with it at any level; as you wish. You also not getting changed if your user base is less than 50k.