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.
Related
we use Aws Api Gateway to protect our apis.
We want to create an sdk for developers. The idea is to have In app purchase in their apps and call our apis in order to start payment.
We are trying to have a way to connect machine from machine. The first machine will be an sdk integrated in Android games and the second will be our back end protected by the api gateway.
The sdk should have a the authorization to consume the api.
Today we don't know how to do it, even after discussing with many architects.
The sdk is not going to have user and password, because it is not a user, so no way to generate the classic access token.
How could we achieve this use case ?
Thanks
The sdk should have a the authorization to consume the api. Today we don't know how to do it, even after discussing with many architects.
There are three possible ways to have a protected API Gateway. AWS Cognito and AWS Lambda. The third option, API Keys, is a little bit different than the previous two.
With Cognito, you create user pools and API Gateway automatically handles authorization when a request is received.
With Lambda, you create your own custom authorization logic.
I generally prefer the Lambda approach due to the ease of use but it depends on the use-case.
With the API Key option, you create API Keys for specific routes and API Gateway checks them through the request headers. I think any use-case that requires this can be handled with the Lambda option as well.
What you are describing doesn't sound difficult to achieve.
You will generate an API key and you will give them to the developers that will use your API.
In your SDK, you can accept the API key as an initialization parameter and provide it in the requests to API Gateway.
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'm trying to integrate Cognito Authorizers into an existing application that is using API Gateway to authorize requests.
The documentation insists on using AWS Amplify to make these calls, but I'm not sure that this fits in well with the existing architecture since Amplify seems to have its own way of making API requests, and I'm worried that it would mandate having to change all of the existing API requests...
So my question is if there are more readily integratable solutions to this problem, or if my concerns are unfounded.
There are several SDK's that can be used with Cognito.
You can use the AWS js SDK to make low level API calls but you will lose the benefits that the Cognito Client Side SDKS provide like session management, caching of tokens and SRP calculations.
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html
You can also use the Cognito Identity SDK which Amplify uses under the hood:
https://www.npmjs.com/package/amazon-cognito-identity-js
The Auth SDK if you are going to be integrating with the OAuth endpoints, which is now deprecated but can still be used or referenced, Amplify also uses or has similar functionality.
https://github.com/amazon-archives/amazon-cognito-auth-js
And then finally Amplify which is the go to, feature rich client side SDK which for the majority of usecases should be the SDK of choice in my opinion.
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.
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.