NestJS - JWT Authentication with microservices - jwt

I am currently playing with NestJS' microservices and authentication, and I am facing a problem for which I don't have a clear solution.
Let's imagine I have an API gateway balancing the calls to multiple microservices.
I would like to enable authentication (via JWT tokens) and retreive the user information for every process I might call on any microservice.
The problem I am facing is that I don't know where to decode the token.
Should the API gateway decode the token and proxy the HTTP request to the microservice by appending the user data to it ?
Should the end microservice decode the token instead of the gateway ?
I feel confident implementing both of them, I just cannot figure out if they are good practicesor if there is a better solution I haven't thought of yet.

The best way to do this by use the flow in below.
Request go from client to API gateway.
API gateway will call auth microservice to decode the token.
Auth microservice will verify this token and decode it. then call db to get user data then send user data to API gateway.
Now API gateway have the user data. then will inject headers like x-user-id, x-user-name, x-user-email. and call microservice-x.
Lets say microservice-x will create and record in table then call microservice-z to send email.
Microservice-x will receive request to create record in table for user id x-user-id. then call microservice-z to send email by x-user-email.

Related

Pass Cognito User Info to HTTP Integration

I've been exploring utilizing Cognito User Pools for authentication and API Gateway to feed client requests with auth tokens. I'd basically like to have a simple react app that utilizes the cognito sdk for authentication. Then use the authentication to make requests via the API Gateway to an express application, hooked up to cognito user pool auth. It would be ideal to have user information available in the express app - seems pretty simple to me.
I've seen many articles and forum posts about how to retrieve Cognito User Info in the context of a lambda function but nothing about how to retrieve Cognito User Info in the context of an HTTP Integration.
Is this possible?
Yes, it is possible, and can be achieved in, at least, two ways:
Proxying requests with original headers
If you enable "Use HTTP Proxy integration" in your HTTP integration, the API Gateway will act as a proxy and forward any headers in the request to the backend (and same from the backend response back to the client). This means that the JWT will reach the express application in the same header the client sent it, where it can be decoded and the claim(s) retrieved.
Using request [and response] data mappings
Another way is to pass the required claim(s) in the Path/QueryString/Headers mappings for the Integration Request, using context.authorizer.claims.{claim} in the mapping, e.g. context.authorizer.claims.email. You can see the documentation on setting up the data mappings and also the mapping reference for more variables that can be used. Please note that for context variables the right syntax to use is without the $ prefix.

How to provide OAuth through services?

I have 3 services (in the real much more):
Authorization service (uses OAuth 2.0)
Frontend service
Resource service
and client (web-browser).
I store session_id, access_token and refersh_token in cookies of the user's web-browser. The user goes to Auth service, signs in and gets these tokens. After his web-browser is redirected to Frontend.
Frontend and Resource services can't validate tokens because they know a nothing about it, so they must make a request to Auth service.
The current scenarios:
The user (web-browser) sends a request to Frontend service, the Frontend sends a request to Auth service to validate access_token. If it's invalid the Frontend sends a request to refresh token using refresh_token.
If the Frontend needs an access to Resource service to process a request then the Frontend sends its client_id and access_token to Resource service. The Resource service sends a request to the Auth service to validate an access_token too.
Are my thoughts right? Or it has simpler schema?
P.S. All services use RESTful architecture.
OAuth talks about how the tokens be exchanged. What you have mentioned it seem liek you are talking about using implicit grant, which is little less secure and you may think of opting for authorisation flow.
Other than that, in microservices when you have many services and one user request pass through many downstream services, verifying the token with auth provider at each and every step might become a bottleneck.
There are ways out there by which you can skip this call to auth server and still validate the sanctity of the token without making an explicit call.
One way is to make use of JWT. These tokens are signed by the Auth provider and your services have keys which can help you validate if the token is modified on it way, and token itself has all the information you need to ensure validity of it, like expiry time, intended audience, clients, roles etc.
On login you get AT and RT. AT could be passed along to downstream for authentication and authorization and RT could be used when AT is expired.
You only need to talk to auth provider at the time of login and when you need to refresh the token.
You can read more about the JWT OAuth2.0 with JWT and OIDC to get more information around it

Central JWT authentication / authorization service

I am in the process of setting up a central JWT authentication / authorization service. We will have multiple APIs that a client will need to communicate to and be authenticated against.
My thought was to have the user login, which would authenticate against the JWT server. It then uses that token to communicate with the other resource APIs. Those APIs would validate the token against the JWT server before sending the request back.
Is this a pretty decent approach to the problem? Has anyone implemented something like this? One issue I see right away is there is a lot of communication to the JWT server.
This sounds like a decent approach. I have implemented a solution where the JWT service was a part of my API. As i understand from your question, you want to have this JWT service separately so that a user can interact with different services/application using the same token. This is called Single Sign On.
If you think your JWT service is getting a lot of traffic, you can always spin up more instances to handle the additional load.
As long as your service is just getting token from a database and responding to request quickly and not doing any calculations, i do not see it getting affected by a lot of traffic.

webapi rest... is best practivce to avoid SESSION

I am creating my first webapi project using ExtJS for the client-side and trying to understand login procedures. I'm trying to understand what SESSION is used for and if I use REST, SESSION should not be part of it.
REST by design is stateless. By adding session (or anything else of that kind) you are making it stateful and defeating any purpose of having a RESTful API.
The whole idea of RESTful service is that every resource is uniquely addressable using a universal syntax for use in hypermedia links and each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP".
I'm a bit confused on session... normally, when a user logs in the sessionID is recorded somewhere on server? Then when user makes another request, url sends this sessionID back to server and if the ID is valid proceed with request.
Do I have this right?
On the other hand with rest the request message basically sends the username/password everytime a request is sent.
Do I have this right? Using REST on my webapi, can I skip the whole concept of SESSION and just keep sending username/password... or is there a better way?
can I skip the whole concept of SESSION and just keep sending
username/password... or is there a better way?
Yes, Web API has Token based Authorization - Bearer token. By using it, you can totally avoid using Session State.
Secure a Web API with Individual Accounts and Local Login in ASP.NET Web API 2.2
In a nut shell, when a user is successfully authenticated, server issues a token instead of session state. Then every request, the user sends the same token along with the payload.

Can I avoid session authentication in my web service without having to validate the username/password in each request?

I am building a RESTful web service using ASP.NET web API. I've read that it isn't very RESTful to use session authentication since a "login" request is required before any other request can be successfully made. In addition, it requires the client to maintain state.
My original design was to have the client call a "login" request using basic HTTP authentication over SSL. The web service would then verify the credentials and respond with a session key. The client then uses that session key to sign all subsequent requests. When the web service receives any of these requests it looks up the session key, signs the request in the same way, and checks if the two signatures are equal.
Is it possible to avoid this session authentication without having to send the username/password with each request? The credential verification does not happen within the web service (it is routed to another server that maintains users). I'm concerned that performance will be affected if I need to validate each request.
It's not possible. You either store the state or get the credentials with each request. The second option is what you would want with your HTTP API.
Depends what you mean with "validate"
you could e.g. cache the hash(username+password) in your application. And on subsequest requests check if the cached entry still exists. This way you can save roundtrips to your backend store.