NodeJS Authentication for Multiple RESTful API services - node.js

I would like to seek help from you guys.
I have multiple RESTful API services running in NodeJS Express. Each API is hosted by different NodeJS with different port. And in our front-end, it is accessible via reverse proxy.
We are now moving to a secured services. However, there's a problem in authenticating with the services. The front-end should request 1 auth token upon login that can be used in accessing the internal API services (API is also accessible in our public domain /api/).
How can we solve this problem?
Current Setup

You could issue a signed JWT token upon login (see https://jwt.io/).
The front end application has to send the token back with each API call.
Each API server has to know in advance the key (public key or symmetric key depending on the type of the signature algorithm) and use the key to check the signature of the token is valid.
If it is valid, the API server knows it can trust the token content, and decide whether to serve the request. The token would contain the identity of the user, expiration time, ...
Note that signing the token does not encrypt the data: if you need to convey sensitive data through the token, it needs to also be encrypted
Thus it is not necessary to establish a session and then share the session across the many API instances. Knowing the key is enough to trust the token content
To pass the JWT in API calls you can use a header:
Authorization : Bearer theBase64EncodedToken
Of course, it is up to you to check if this scheme satisfies the security concerns related to your application.

Related

How do you secure information between 2 servers?

Forgive me I'm still very new to this.
I am building multiple front ends which all need to be able to speak to a single back end server api. These front ends are hosted on different domains so I ran into CORS issues and from what I've gathered my best solution is to send the appropriate data on the front end to a proxy server on the same domain which then forwards that request to my api server.
I'm concerned about the security of this action though and looking for the right way to secure the data being passed from the proxy server to the api server.
So my data goes:
client --> proxy --> api
and I want to know the best way to make sure the api knows the proxy is who it claims to be. Is my best bet just a simple password exchange? A json web token?
Yes, you can use JWT actually. The proxy server can send a JWT along with each request to the API server, and the API server can then validate the token to ensure that it was issued by a trusted source.
Here's a scenario how JWT authentication might work in this:
The client makes a request to the proxy server, including any data
that needs to be sent to the API server.
The proxy server generates a JWT, which includes a unique identifier
for the client and any other relevant information, and signs it with
a secret key.
The proxy server sends the request, along with the JWT, to the API
server.
The API server receives the request and extracts the JWT from the
header.
The API server validates the JWT by checking the signature against
the secret key and verifying that the JWT has not been tampered
with.
If the JWT is valid, the API server extracts the client identifier
and uses it to determine whether the request should be processed.
If the JWT is not valid, the API server returns an error response to
the proxy server.
Note:
It's important to keep the secret key used for signing the JWT secure, as it is the key to ensuring the authenticity of the JWT. It's also a good idea to regularly update the secret key to further enhance security.

Authentication architecture of VueJS(or React or Angular) application in front end using authorization code grant

I am working on an application where the front end is VueJS and the backend is NodeJS and ExpressJS.
The NodeJS, ExpressJS will be hosting REST API's and I want to secure them using Azure AD. I want to use Auth Code flow.
My question is: I have put my thoughts in the diagram, is this the right approach?
This approach looks good to me. I am thinking of it as an advanced version of something like JWT (https://jwt.io/) based authentication. Please see the steps below for JWT:
The client requests authentication by providing credentials.
The server provides the client with the token that is encrypted using the private key present in the server.
The JWT is stored in client's session and is sent to the server anytime the client requests something from it requiring authentication.
The server then decrypts the token using the public/private key and sends the response back to the client.
A session is validated at this point.
With the architecture you have described above, it does the exact same thing except the means to encrypt (generate) and decrypt (verify) the token exists with Azure AD. Below are the steps for achieving authentication based on your architecture:
The client requests authentication by providing credentials.
The Azure AD server does a 2FA kind of thing but in the end provides the token (equivalent to JWT in the previous approach).
The token is stored in client's session and is sent to the application backend server anytime the client requests something from it requiring authentication.
The backend server uses Azure AD for verifying the token (similar to the decryption/verification step of JWT) and sends the response back to the client.
A session is validated at this point.
I would suggest a small change to this though. If you look at the step 4 above. The application server will keep hitting Azure AD every time it needs to authenticate the session. If you could add an actual JWT for this phase, it may help in avoiding these redundant calls to Azure.
So the steps described above for JWT may be added after the 4th step for Azure AD described above i.e. create a JWT and store it in clients session once everything is verified from Azure and then keep using JWT based authentication in the future for current session.
If required, JWT can be stored in the browser cookies and calls to Azure AD can totally be avoided for a specific period. However, our objective here is not to decrease load on Azure AD server but just suggesting a way of using JWT in this specific situation.
I hope it helps.

What are the recommended strategies for authorising API calls from my react native application to my node server?

I have a react native application that I want to make API calls from. I am getting confused about how I should be authorising these calls on the node back end.
Method 1:
User logs in to application and authenticates, I then return a JWT with refresh token. This is then stored client side / in react native app and is sent upon each request. If token expires, then refresh using refresh token.
Method 2:
Create API key for each client. When a user creates an account, I create an API key (or maybe access key and secret key like AWS does) and send that with each request.
Is there a preferred / recommend method out of these two? Perhaps they are not mutually exclusive? Do I still need to provide an API key to my react native app so that it can make API calls and then I use JWT for authenticating users?
In my personal opinion,
You may go for the Method 1, since it is not secure to store / create API keys or Secret keys on the client side.
JWT are more secure, you may read the following article
In the Method 2, you will most probably try this approach
Generate Api key based on client IP or the device token, whatever suits you, and set an expiration time including the AES techniques, then decrypt it on the server, check the client's IP against the requestor IP and also the expiration time.
Complexity and time taken to do Method 2 is much more that Method 1, also considering I might have not covered all the security use cases.
Do I still need to provide an API key to my react native app so that it can make API calls and then I use JWT for authenticating users
You can make the http calls normally. The recommended way is call your token generation api and then authenticate other valuable api's based on that token if you're using JWT
Hope it helps.

Using SAML with JWT for Node API

I'm building an Angular 2 application using SAML2 via the passport-wsfed-saml2 strategy https://github.com/auth0/passport-wsfed-saml2. When I receive a users info back from SAML I generate a JWT token which I use to authenticate a user on an API I am also writing.
So I have two servers, APP/Auth Server is serving my application as well as generating my JWT tokens and API Server has my API. Both servers have a copy of the JWT secret, so when a user sends a request from APP/Auth Server to the API Server I verify the token they sent with their request by verifying it with the secret.
Now for my questions, is it bad practice to have your app served from the same server you use to generate your JWT tokens? If so, what should I do here? Should I be doing more to authenticate a user on my API side?
Something about this just feels dirty....any help would be appreciated.
Having the application and authentication system in the same service is not a malpractice by itself. In general, decoupled services are recommended but this does not mean that the deployment can group services and of course depends on the context
If you are worried about sharing the secret key among servers, you can use an asymmetric key pair (private and public). The private key only needs to be known by the Auth Server in order to sign the JWT. The API Server can use the public key to verify tokens.

Microservices authentication architecture with passport.js

I'm writting a toy application for practicing microservices and authentication on nodejs (expressjs).
I have a react client, an authentication service and other services (they just respond "Hi" so far).
The client will be hosted in a CDN.
The auth service listens on port 5000 (for example)
The rest of the services listen on port 6000-6100.
I have a redis db to store session information (oauth token provided by twitter).
A mongodb where the application information is stored (not relevant for this question).
The idea is that an unauthenticated client goes to the auth service by clicking the Twitter button (SSO). Then the auth service obtains the generated twitter oath token and it sets this token in the redis store. Then the token is accessible to the rest of the services so they know if a request is authenticated or not by checking if the it already exists in the redis store (if the user removes its account, it will also be deleted from the redis store).
I send the twitter token back and forth from client to server once authenticated.
I find this approach pretty simple (others use an nginx proxy for authentication but I see no reason for that, except if the services are hosted in different domains, but I don't understand it very well) so I'm worried I'm missing something about security for example.
Questions:
Is this approach correct?
Is it safe to share the twitter token (I think so)?
Is there any security issue I'm not noticing here?
Using this approach you will have to validate the token in all your services, if you are okay with this then you are probably fine.
The twitter access token may have an expire time that will make it necessary to use a refresh token to get a new access token from the auth service:
When the access token expires you would return a 401 to the client, from the Service X that you are trying to talk to.
The client would have to call the Auth service providing a refresh token, getting a new access token
Finaly the client would be hitting the Service X again with this new access token, have it validated and get the expected response from Service X.
In my recent assignment I wrote a micro-service that proxied all the tokens, using this approach my proxy handled everything from auth to roles and sending 401's for expired tokens and revoking refresh tokens etc. I think this gave me a greater separation of concerns.
Important Note: In the refresh token scenario above my proxy only would experience load for an invalid/expired accesstoken, whilst in your scenario any service could be reached with invalid tokens...
Another approach would be to let Service-A and Service-B call the auth service to validate the tokens, but this would infer a lot of more traffic between the services since each HTTP request with a token has to be validated. In this scenario as well a invalid token request would reach your Service X and hence infer some load on it...

Resources