I have been making a web app. (Angular 2 on S3 and APIs in lambda through API gateway). For authentication I played both with cognito and custom authorizer (I configured my authentication to work with Google and Facebook bith via a custom authorizer and cognito). In case of custom authorizer I am passing a token via authroization header and my custom authorizer validates it.
I am looking for advice on which should I go forward with and what are their pros and cons. Ones that I could think of are:
AWS cognito:
Pros
- AWS SDK handles everything for you and you cannot make much mistake in your authentication process.
- Fine grained access control for AWS resources via IAM.
- An extra lambda function in front of every API is not required for authentication.
Cons
- Need to use AWS SDK specifically on client side. Programmers have to add this into their toolchain and make use if it during development. Adds extra complexity.
- Fine grained access control for resources is not really required since the only access that is required is for API gateway.
Custom authorizer
Pros
- You can have your authentication mechanism the way you want it. Ultimate control over authentication and authorization.
- You can have the UI call the APIs with a standard token (JWT) and the flow for developers remains same. No extra consideration of AWS SDK.
Cons
- Authentication requires a lot of thinking and effort to build.
- Chances of missing some crucial aspects are always there.
- Its like reinventing the wheel. Why do it when Amazon has already done it for you.
All that being said, I am leaning towards custom authorizer for now. Need advice here on the topic.
PS: I know there cannot be a definite answer to the question I have posted but it would be of great help to people trying to decide on authentication for their applications.
2
Answers
okay, authentication and security is indeed hard and there are a lot of issues that have been thought about and taken care by AWS security team that you may not think of and implement and make your application insecure. I implemented my custom authorizer to expect an authorization token (passed through authorization header) that was a base64 encoded value which would repeat across all the requests in a session. It turns out that due to weaknesses in RC4 and diffie hellman this makes the TLS susceptible to attack. If we simply use cognito using IAM then AWS sigv4 request signing protects you from these weaknesses. Watch https://www.youtube.com/watch?v=zmMpgbIhCpw for more details.
Another benefit of using cognito/IAM is that it protects you against CSRF replay attack. Request signing involves using timestamp. IAM will deny any requests that are signed more than ~5 minutes ago.
In short avoid using custom authorizer if you can and use IAM with cognito. You will thank yourself.
This is a short answer but, why not use both of them?
Use a custom authorizer that is actually implemented to use Cognito Users Pool and Cognito Federated Identities.
When you use Cognito you can make the choice not to use everything.
For example I set up a custom Authorizer and my Lambda is actually using Cognito Users Pool API to authenticate the user. I let Cognito Users Pool to handle all the passwords, tokens, etc..