Authenticate session with AWS API Gateway - amazon-web-services

Situation: I have an app (Next.js/React on Vercel) running on example.com. I have an api (AWS API Gateway) on api.example.com. Currently the application on example.com supports login using Auth0 as authentication provider.
Problem: I would like to be able to make authenticated requests from the application (example.com) to the api (api.example.com).
Architecturally, I was hoping for a way for the API Gateway (api.example.com) to handle the authenticated session from the app/Auth0 cookie (example.com). I thought the browser could share the cookie (since api.example.com is trusted) and the API could validate it.
But I don't see a standard way to do it. I think I could try to create some custom lambda authorizer for AWS' API Gateway. But since we're dealing with authentication, I would prefer to outsource as much as humanly possible and avoid any custom code. I just can't seem to piece together the way for API Gateway to handle the sessions, which I assumed would be a pretty common problem to solve.
Sidenote: Previously, I used the pages/api that's baked into Next.js to directly call Lambdas on AWS and expose them. With this, authentication natively works. That's the experience I'm now trying to recreate, but without the user having to take a roundtrip.

When you want to protect APIs it’s better to use JWT tokens to carry over necessary claims e.g. id of authenticated user. OpenID connect and Oauth2.0 are the standards to look into.
Auth0 has documentation of recommended authentication flow: https://auth0.com/docs/flows/authorization-code-flow
as well as example with Api Gateway’s HTTP apis: https://auth0.com/blog/securing-aws-http-apis-with-jwt-authorizers/
AWS documentation has more info about Http Apis and JWT token authorizers: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html
If your Api gateway is using Rest apis instead of more light-way Http apis then token based Lambda authorizers are the right solution: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

Related

Implementing a backend-less auth mechansim

I would like to implement an SPA which bounces the user to a login page, if not already logged in. It would then able to make a call to an API (not necessarily an API Gateway) hosted within an AWS VPC.
As I currently understand it, this would involve a front-end framework library authenticating the user via OAuth 2.0. It would then need to retrieve a token (allowed because of the auth validation) to call an API Gateway which provides access to the API hosted within the VPC.
Given this concept, is this architecture possible without the use of a Lambda?
If you are willing to use API Gateway in front of your API:
Yes, this architecture is possible without using a Lambda. API Gateway has integration with AWS Cognito User Pools for authorizing requests. You can find the AWS docs on how to set this up.
If you don't have an AWS API gateway in front of your API:
In this case you will have to implement one of the authentication and authorization flows provided by OAuth 2.0 standard. In this case, whether you would want to use a Lambda or not, is up to you and your back-end architecture.

is ok to choose AWS HTTP API gateway for a mobile application?

I am trying to decide which aws apigateway version choose for my application (HTTP vs REST API gateway).
I am experimenting with AWS HTTP API gateway to see if it works fine for my use case.
These are my requirements:
The only client is a mobile application
The rest API can be accessed only from logged in users
I want to use cognito with cognito authorizer
My backend is a mix of lambda services and HTTP rest services exposed via an internal application load balancer
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
Are there any security concern if I go for HTTP without any api key?
What would be the right way to restrict the access only to requests coming from my mobile app?
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
HTTP APIs support OpenID Connect and OAuth 2.0 authorization
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html
If you have any custom api-key, you can still have an authorizer lambda to authenticate and authorize the client.
Are there any security concern if I go for HTTP without any api key?
What do you mean by the api-key? API-key is usually static shared secret used mostly in the backend application. Claiming the users need to be authenticated and using the mobile app, having a hardcoded api-key is not the best idea (read - it is a terrible idea)
Under these requirements the default option is using OAuth2/OIDC for user authorization and passing the user's access token along the API requests.
What would be the right way to restrict the access only to requests coming from my mobile app?
I want to use cognito with cognito authorizer
The simplest and built-in way is using the access token from Cognito and built-in JWT API authorizer. Yet you may configure any other option.

How to authenticate requests in AWS API Gateway securely with a web app

I'm trying to make an AWS API Gateway endpoint that can authorize my JWT.
This is not possible with custom (Lambda) authorizers because they require a signed Authorization header which requires an IAM User's AWS Access Key and secret. An untrusted source, like a web app, cannot keep secrets, so we can't bundle the Access key into the client-side app. Therefore, this custom authorizers aren't suitable for web apps.
The only way to implement authentication of a JWT in API Gateway is to implement the authentication logic into the Lambda function itself.
Does anyone disagree? Are there security flaws? Is this a misuse of API Gateway?
This question as been asked before here and here, but never adequately answered.
Please use Authorizer in API gateway for achieving this. There are multiple Authorizers possible in API Gateway.
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html

Using AWS API Gateway for Lumen based REST API Service with Passport authentication hosted in EC2

I am entirely newbie in Amazon Web services. Currently i am developed a REST API service using Laravel's micro frameworks called Lumen. I am using passport for token based authentication and all that working fine. I need a proxy server to hide my actual endpoints and do some other functionality so i am planning to use AWS API Proxy Gateway and host the API endpoints in EC2 instance.
i went through Build an API with HTTP Proxy Integration from Aws documentation. but there is nothing about using a custom authentication using Oauth.
My Doubts are
How to use Passport authentication when using AWS API Gateway
Is there any good method to hide my REST Endpoint from customer and need a way to change the proxy end point from time to time.
I don't know Laravel ecosystem, but:
if passport expose something like an OpenId Connect you could use Cognito Federated Identities for, precisely, federate your identity, and associate the authorized identities with a given IAM role and unauthorized with another role;
you can use an Api Gateway Custom Authorizer to perform fully customizable auth;
Try expanding your question so we could add more details...
Yes, like what BAD_SEED said, you can use API Gateway Lambda authorizer (formerly known as the custom authorizer) to do any logic to verify the token, since it's just a javascript package.
So, one option is like what auth0 does in (https://auth0.com/docs/integrations/aws-api-gateway/custom-authorizers/part-3) and (https://github.com/auth0-samples/jwt-rsa-aws-custom-authorizer). Their sample authorizer does followings:
It confirms that an OAuth2 bearer token has been passed via the Authorization header.
It confirms that the token is a JWT that has been signed using the RS256 algorithm with a specific public key
It obtains the public key by inspecting the configuration returned by a configured JWKS endpoint
It also ensures that the JWT has the required Issuer (iss claim) and Audience (aud claim)
But unfortunately, Passport does not support JWKS endpoint (which exposes public key for the token signature). So you may have to expose it by yourself.
Another option is much easier, you just make a token verification endpoint in your application, something like /users/me, and protect it with auth middleware. Then in your Lambda authorizer, call it with the token in the request to your other micro service endpoints. By this way, all token verification stuff is left to Passport, and the authorizer just executes policy based on the result of the verification.
Not very sure about what you want to reach, but API Gateway is just a proxy, so you can certainly change backend side endpoints for its frontend one, which is better not changing so often.

How to secure the APIGateway generated URL?

I have a serverless backend that operates with APIGateway and Lambda. Here is my architecture:
Currently, anyone with my APIGateway's URL can query or mutate the data. How do I protect the URL, so that only the client(react app) can access it. So, here is my concern, anyone can open the network tab in chrome console and get my APIGateway's URL and can use it using curl or postman. I want to prevent that.
Solutions I had in my mind:
Set up a CORS, so that only the origin can access it. But, I have a different lambda that invokes this URL. So, CORS wont work out.
I am sure there are some methods with the APIGateway itself. I am not getting right search term to get it from AWS documentation. I would also like to know what are the best practices to prevent accessing the backend URL apart from the Client(React App)
Update after #Ashan answer:
Thank you #Ashan for the answer. In my case, I use Auth0, so custom authoriser should work for me. I just came across this https://www.youtube.com/watch?v=n4hsWVXCuVI, which pretty much explains all the authorization and authentication possible with APIGateway. I am aware that authentication is possible either by Cognito/Auth0, but I have some simple websites, that has form, whose backend is handled by APIGateway. I can prevent the abuse from scraping bots using captcha, but once the attacker has got the URL, header and request parameters, he can invoke that million times. One thing, we can do is having an API-Key, but it is a static string with no expiration. Once the headers are with him, he can abuse it. So, any idea, how to prevent this in APIGateway. If not any other service apart from AWS that I can look for? Would be glad, If I get an answer for this.
Currently API Gateway does not support private urls, so it will be publicly available.
To restrict access you need to use a authorizer to authenticate and authorize the request using IAM policies. There are two options available at the moment.
IAM authorizer
Custom authorizer
If your authentication flow can directly (AWS STS, IAM user access keys or roles) or indirectly(Using AWS Cognito Userpools or any other SSO provider) can get temporary security credentials, then you can use IAM authorizer. From API Gateway side no code involved and its a matter of selecting the IAM check box for each API Gateway resource. You can use the API Gateway SDKs to invoke API Gateway requests where the SDK will handle the heavy liftings in setting up authentication headers.
If you use your own authentication mechanism, then you can write a seperate Lambda function to validate the tokens. This Lambda function name can be specified at API Gateway with the http hearder name to access the custom token to verify the requests.
To control API usage by authorized consumers, using API Key is the only way native to AWS at the moment.
Since you are using S3 for the react app hosting, you can further reduce the attack surface by using AWS WAF and CloudFront infront your application stack. The API Key can be added to CloudFront headers to forward to your APIGateway origin and since CloudFront and APIGateway communication happens using SSL, its nearly impossible for someone to find the API key. Using AWS WAF you can limit malicious access for common attacks. This includes rate based blocking to limit someone from repeatedly invoking the API.