validate userId given by okta - node.js

I have an app which consists of frontend server and a backend server.
front end server connect to corporate OKTA mechanism so that user logins through their corporate ids into my app.
After this step, frontend server connects with some backend work at backkend server (node js). Their it passes in the request body the user id so that we can finally log that the below processing is happening due to user X.
Now suppose user A logs into the app . Now during the APi call to backend server, he can modify the arguments being passed to the api and somehow change the userID.
Is there some way by which backend server validate that userID is not compromised ?
Regards

If your front-end app uses OIDC to log a user in, then you should be able to get back an id_token, which has user identity in it. You can pass this token to your back end app for API calls. This approach is not ideal though, as your backend will still have issues with trust, as it does not know if the token presented by the front-end app is a legitimate one and not stolen.
Other way is to harness traditional authorization_code flow (again, assuming you can do OIDC with you company's identity provider). There your back-end would retrieve the tokens for you directly from authorization server and can get a user's identity from it. Based on that it can then create a session and embed user info into it. It's a bullet proof approach lacking trust issues from above.

Related

SAML-Authentication using angular, node.js and an identity provider

I want to to implement SSO using SAML2.
But I don't know how to get it work with a distributed system where each instance is running independently on its own server. The environment consists out of three instances:
Instance #1: an angular frontend
Instance #2: a node.js backend (using express.js + passport)
Instance #3: a SAML instance (identity provider)
The question is what would be the best approach if the frontend calls a guarded backend route?
Which sequence of actions can be seen as good practice?
At the moment I have this behaviour in my mind:
The frontend sends a request to a guarded backend route
Because the user isn't authenticated, the server initiates a redirect to the SSO-Page provided by the identity provider.
There the credentials are entered
The user gets authenticated by the saml instance and it sends a request back to the server.
Now the user is authenticated, the server sends back the response with the requested resource to the client.
But as long as I think about this sequence I realize this couldn't work.
Its because the frontend is its own instance and it is independent from the backend.
The redirect to the SSO-Page initiated by passport don't work if you have a separated frontend instance.
It works if you call the guarded route directly with the browser, because then you have only two communication partners (service provider & identity provider) instead of three.
But this is not the case here.
Thanks and regards
Philipp
I've done something similar in a previous job with this logique:
Implement a login page in Angular (Simple Form to get credentials),then call a login service in the backend.
That backend login service should verify the credentials provided by the frontend against the identity provider (I'm sure they would provide you an url where you can inject these params).
Once the identity is verified, call an athentication service in the backend to generate a token for this user (Passport JS should do the job) then send back this token to the frontend.
In the frontend, implement a guard which should handle token/ set user credentiels into local storage...
In the frontend, implement also an interceptor which injects this token in every XHR header or redirect the user to the login form in case token is absent or expired.
In the backend, the logique will be classical (verify token validity from XHR header before sending back data / tell the frontend to login if the verification fails).
With this logique you'll keep the frontend away from the identity provider and in coherence with the backend.

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.

How to let frontend know your server has successfully retrieved an access token

I've been studying the OAuth 2.0 authorization code flow and am trying to write a React application with an Express backend that displays what a user would see on their own Instagram profile. I'm trying to do so with minimal external libraries (i.e. not using passport-js) and without bringing a database into the mix.
This is my flow as of now:
Resource owner clicks an <a> tag on the React application (port 3000) which redirects them to the /auth/instagram endpoint of my Express server (port 8000)
res.redirect(AUTHORIZATON_URL) sends them to Instagram's authorization server
Resource owner consents and the authorization code is sent back to the predefined redirect-url /auth/instagram/callback with the authorization code set as a query parameter
I strip the authorization code off the url and make a POST request to https://api.instagram.com/oauth/access_token to grab the access token
Now that I have the access token, how do I reach out to the React frontend to let them know that everything worked and that the user was successfully authenticated?
From what I've read, this is where the idea of sessions and cookies come into play, but I haven't had luck finding documentation on how to achieve what I want without bringing in third party libraries.
In the end, I would like for my app to support multiple users viewing their profiles simultaneously. Since I imagine passing the access token to the frontend defeats the purpose of securely retrieving it on the backend, I'm guessing I will somehow need to pass a session id between the frontend and backend that is somehow linked to an access token.
Any ideas as to what my next steps should be are greatly appreciated, as well as any articles or documentation you see fit. Thanks!
Since you're doing the OAuth authentication on the server side, you have to pass some parameter to the redirect_uri, identifying the user session (see: Adding a query parameter to the Instagram auth redirect_uri doesn't work? );
When the redirect uri is called from the authority server, you will know which user was authorized. To notify the browser there are two options: 1) Notify the client using web sockets; 2) Pull the state from the client using a timer triggered function;

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...

PHP REST API Key and User Token Authentication

I wanted to check with you guys if my API Key and user Authentication scheme makes sense or not. My server side code is in PHP and the Database is MySQL. This is the scheme I have in mind:
I am implementing a REST API in a backend server that will be called by a Mobile App (for now). At this point, I only want known Mobile Apps to connect to this API. So I am using a one-time API Key that has been given to the Mobile App during installation. Every request from the App passes the API Key that my API checks before going further. This Key is stored in a Database table. This completes my API Key checking and seems to allow only known Apps from calling my APIs.
Next, I also have certain services after calling the API which only authenticated users are supposed to get access to. For this, the Mobile App logs in with a Username and password which is authenticated in the User table of my Database. If it passes, the server generates a User Token and passes it to the Mobile App. The User Token is also saved in the User table against that User. All subsequent requests from the App (which requires user authentication) passes this User Token which is checked in the User table in the Database for User Authentication. If the Mobile App logs out, this User Token is deleted from the User table. I also have provision to add "TimeToExpire" for this User Token which I will implement later.
I would be really grateful if you guys could tell me the following:
Does the above structure makes sense for App Authentication and User Authentication?
I am a little lost as to what will happen if I ever need to change the API Key (for whatever reason). Not sure how that will be sent to all the Apps. Google Messaging seems like one possible way to handle that.
For the App Authentication, does it make sense to keep the API Key in a Memcached object? Since all requests from the Apps are authenticated, I don't want to go to the DB everytime. And pros/cons?
Along the same lines, does it also make sense to have the User Token in a Memcached object as well? Pros/cons?

Resources