Using AWS API Gateway for Lumen based REST API Service with Passport authentication hosted in EC2 - amazon-web-services

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.

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.

Authenticate session with AWS API Gateway

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

authentication with Cognito pool per tenant

I am watching an AWS reInvent video: https://www.youtube.com/watch?v=kmVUbngCyOw&feature=emb_logo&ab_channel=AmazonWebServices where it suggests to use Cognito pool per tenant.
This is what the authentication looks like and introduces an Auth manager to Auth against Cognito and gets back a JWT token based on OpenIdConnect.
I was reading another blog post here: https://medium.com/#tarekbecker/serverless-enterprise-grade-multi-tenancy-using-aws-76ff5f4d0a23
and It suggested using a Custom Authorizer attached to the API gateway.
Am I right in understanding that we should basically be authenticating in 2 places ->
From the web app using Auth Service
At API gateway using custom authorizer
Generally, people use the AWS SDK to authenticate the user from Cognito and it handles the whole authentication logic. AWS-SDK is available in almost all popular languages.
As API gateway is the frontline service or the publically exposed service through which you can access the microservices hosted using Lambda. Also, ApiGateway interacts as an intermediary/broker service between any client application including Web and Lambda microservices.
Custom Authorizer is used for implementing the custom authorization logic at the API Gateway service i.e. if a user role doesn't have any access to certain Apis it'd just give an error to the user trying to access those resources.
For example how we used Custom Authorizer in the past. We had users with 2 role types
Admin
User
We had to restrict the access of the admin Apis. So we added all this logic to authorize access to the Apis based on the information we get in the bearer token.
https://aws.amazon.com/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/

Do I need to verify a AWS Cognito token in BOTH Lambda AND as API Gateway?

When using a AWS Cognito attribute from a JWT token in a lambda, do I need to verify the JWT? The Lambda is only triggered by an API Gateway which already verifies the token.
Adding details:
- I'm using Cognito Authorizer in the API Gateway to verify the token.
- The lambda is connected to the API Gateway as proxy.
No you don't need to verify the JWT in backend lambda if protected by a custom lambda authorizer by API Gateway. I would suggest you to use REQUEST based lambda authorizer and attach attributes in the response. So your backend lambda will be able to access attributes in event.requestContext.authorizer['your_attribue'].
This will also enable you to test your Lambda in isolation without needing to get attribute from JWT. You can always mock the event object for unit testing.
I ran into the same conundrum, and was trying to find documented confirmation that, within the Lambda, I wouldn't have to do any validation on my own, and that I can safely rely on the the token / claims being genuine. Unfortunately, nothing in the AWS documentation or the forum posts that I've seen so far has explicitly confirmed this.
But I did find something similar for GCP, and how the API Gateway there validates the JWT. From the GCP documentation:
To authenticate a user, a client application must send a JSON Web
Token (JWT) in the authorization header of the HTTP request to your
backend API. API Gateway validates the token on behalf of your API, so
you don't have to add any code in your API to process the
authentication. However, you do need to configure the API config for
your gateway to support your chosen authentication methods.
API Gateway validates a JWT in a performant way by using the JWT
issuer's JSON Web Key Set (JWKS). The location of the JWKS is
specified in the x-google-jwks_uri field of the gateway's API config.
API Gateway caches the JWKS for five minutes and refreshes it every
five minutes.
So, it seems that within GCP at least, we don't have to do anything, and the API Gateway will handle everything. Even though this is not a confirmation that this is how it works in AWS as well, but the fact that this is how it works in GCP, it gives me some more confidence in assuming that it must be so in AWS too.