creating a multitenant SPA backed by restful web services - javascript

I am trying to create a multi tenant SPA (Single Page App) using HTML5/Javascript. This app will invoke restful webservices for data updates. Below is in illustration to the architecture:
These are my challenges:
Identity : How will a service know that a request coming from a client side JS corresponds to a particular schema in the database? May be I can send an "APPID" token? But, this can be spoofed easily by the end user?
Connection Pooling : If tomcat pool is relied upon for connection pooling, how do I ensure that connections created using "app1" credentials, which has access to APP1 schema are returned to the webservice when it handles requests from App1 JS? I can possibly, just create one database account which has access to all schemas, but this can probably become a compliance issue.
Should I just deploy multiple copies of the webservices? Say, app1 JS queries services.app1.com and app2 JS queries services.app2.com? This would probably solve the above two issues, but I don't think it is a multi tenant solution anymore.

This is normally accomplished by a token that is authenticated. This is normally handled by a standard session cookie (implemented by whatever application server you are using), or something less stateful (like an OAuth bearer token) that gets validated on each call. This is ultimately the same solution, one using a cookie (which is implemented via a HTTP header), the other is using an Auth http header. Regardless, what basically happens is that each user is issued a magic string, which is authenticated on each call as belonging to a particular set of credentials.
It is fairly similar to your "APPID" in theory, the difference is that the tokens are opaque, and very likely unguessable do to their length and complexity (before the heat-death of the universe), and thus are effectively secure. The difference is that you hold the binding between the token and which "APPID" on the server side, not on the client side.

Related

NextJS auth with an external server

I'm working with auth in Nextjs, I'm wondering what is the best strategy to handle authentication in NextJS ?
Here my services structure :
If I understand well I have to handle the server side rendering in NextJS, so I understand I have to put cookies from my external server to my NextJS client, then handle the server side rendering checkings. To do that I assume I have to create connection between the NextJS server and the other services. Before dive more deeper in the subject I would discuss with you about the possibilities available to me. It seems the NextJS auth is a subject in plain development.
Any hint would be great,
Thanks
I've recently added an example with cookie auth which explains what you are trying to do on the frontend.
For the backend, optimally you'll have your API in an external server, apart from the server you use for rendering your Next.js app. This API will handle the database and the token creation business. Then the basics of the authentication are like this:
The client POST a request with username and password to the server.
The server gets the request and generate a token based on the data received.
If everything went okay validating the data, the server responds with the token, e.g., { token: "secrettoken" }.
The client receives the token and saves it in a cookie. Optionally you redirect the user to the /dashboard or /profile if everything is okay.
The client, on restricted pages, will check if the cookie exists and optionally validate that against the server, you do this last part in getInitialProps. If the cookie validation fails you redirect the user away.
I've created a small library to abstract this logic.
So in the end, your Next.js app shouldn't know what's happening in the server, it only should receive the token, save it, validate it, and redirect the user if something is wrong.
How you want to handle the token creation, on the external server, is up to you.
Check out this thread. There are several examples of how to do Authentication with JWT, OAuth etc throughout the thread. You'll see that the examples are utilizing getInitialProps and there are several examples utilizing cookies throughout to extract the Authentication tokens.
You'll have to write a custom server.js file using express.js to serve the tokens through your route requests. I'm assuming by "external server" you mean some third party Authenticator using OAuth or OpenId protocols to retrieve tokens. If so, you're right to say that you'll need to request the tokens (or Authentication mechanism) from those external services and then decide how you're going to utilize them in your own client. You'll probably be using getInitialProps to do what you need to do with your Authentication tokens in the client once you are rendering to the browser.
More examples of Authentication here -- one for firebase and another for Apollo.
Just to add to the answers if you want to use Auth0 specifically. In the interview on http://www.fullstackradio.com/112 around the 1:06 min mark Guillermo Rauch mentioned that if he were to implement authentication all over again he would use Auth0, so I created a minimal repo using Auth0 and Nextjs with Serverless functions.
Like #jolvera suggested there is an API in an external server, apart from the server used for rendering the Next.js app. This API is located in ./auth/auth.js. It handles the token creation business, and could be extended to handle the database.
The HOC component in ./utils/withAuth.js calls the auth.js lambda for the user information, and is only able to retrieve it if the client side is authorized. Otherwise the user information is undefined. Additionally there is an event listener similar to the one in with-cookie-auth which syncs logouts across tabs.
Also one other note, don't get confused with the Nextjs example on Auth0's blog. That example is extending the Nextjs server, and isn't the solution you want if you are deploying Next to serverless. It doesn't have the separation of concerns with page routing and authentication.

Handling client-side authorization with Firebase

I'm building a client that uses Firebase, the Firebase JavaScript SDK, the Firebase Authentication service, and the Real Time Database for persistence.
Following a number of different sources, I have the authentication piece working well, but I'm finding limited options for authorization for what I'd consider an efficient solution.
What I want to do is attach a single key/value of role: 'admin' to the user's auth record so that I can conduct both authentication and authorization with only one client-based call to the Firebase backend.
I've read about attaching custom claims to the Firebase Authentication record, but I've only seen folks using the Firebase Admin library (backend) to both set the token and parse the token. I'm trying to not add additional calls through Firebase functions or a custom Express server, if I can help it.
Adding a separate User profile record to the RTDB is easy, and I can store the auth data there. However, this will always require a simultaneous call for Authentication and Authorization, which, again, seems very inefficient and excludes secure offline use of the client (if roles change on the RTDB).
It also seems inefficient to make a client-based call for authentication, then fire a mandatory second client-based call to retrieve authorization data from a Firebase function (or any other backend service) that can implement the Firebase admin library.
Main question: Is there a way with JavaScript to achieve the goal of setting/retrieving both authentication and authorization data from the Firebase Authentication service with a single request to the backend and processing on the client?
The two options you've given are the idiomatic approaches for custom roles.
If you embed the role into the user's token as a custom claim, you'll get it in the authentication request. Since this is an operation that elevates permissions, it should be done in a trusted environment, such as a server you control, Cloud Functions, or (if infrequent enough) from your development machine.
If you don't want to do that, and want to store it in the database, you'll need an extra request. The overhead of that call is usually not a performance problem.
A combination of the two is also possible: identify the initial "system administrator" UID manually, and then use that in your database security rules to allow the to grant additional rights to other users. But that will also have the roles in the database.
Instead of finding reasons to not use these idiomatic approaches, I recommend implementing one and seeing if your concerns surface in practice.

Angular app protection and user authentication

Implementation of user authentication in Angular app means that application's javascript must be available to user before he is authenticated. That is the problem. What is the correct way to make this happen with Angular? Do I need to implement a separate app for authentication and then redirect users to the base app?
Authentication should be on server level. The angular app should be responsible for only the capturing of credentials, possibly encrypting it, and sending an authentication request to the server with those credentials. The server response(possibly a token) could be used for any further communications with the server to identify the logged in user and its available services.
If the application itself does not contain any private business logic, I don't see value in keeping the application away from the end user even before authentication. On that note, however, take a look at tasks that are used to minify javascript code. This may be second best :)

Moving from Session-based token mechanism to OAuth 2.0 mechanism

I own a Play Framework application acting acting as a backend server providing a set of REST APIs.
At client side, I own an AngularJS application that calls APIs from backend-server through AJAX.
Currently, I make use of a solution based on Session-token mechanism.
Meaning that each time a user logs in successfully, a cookie is retrieved at client side containing an authentication token.
At each request then, the cookie value (the auth token) providing by the client request is extracted on the server and if valid, the request is made.
Now I want to use OAuth 2.0. Reasons are? :
It's a great standard way to secure API, avoiding the use of a datastore (Memcached) to keep auth tokens at server side, as I'm currently providing.
I want to provide a better secure than a sole cookie, by providing some client_secret and nonces to avoid some replay attacks etc...
I want to restrict the amount of clients capable to call even public REST API I provide, meaning API that allows anonymous call, like listing a list of items for instance.
The point is that I don't involve a third party, since all protected resources are on my own.
I came across this article explaining how to secure internal REST API with OAuth 2.0 implementing a 2-legged instead of a 3-legged as usual.
However, I can't figure out how the Client Credentials flow could authenticate a specific user, when calling for a REST API that needs to have a user authenticated.
Indeed, Client Credentials flow seems to be based on a global client_id, client_secret keys (global to the app, so in my case to my Javascript app), and therefore not enough specific to target a specific user and controller its specific rights.
Any help would be great.
Seems like you should use "Resource Owner Password Credentials Grant" (https://www.rfc-editor.org/rfc/rfc6749#section-4.3). It is dead simple - put client ID/secret in Authorization header and put user name/password in query variables. Here is an example from the RFC:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w
Server side you can check for both validity of the client (your javascript app) as well as the user. Just remember that it is impossible to protect the client credentials as it will be embedded in your (downloadable) JavaScript code. The user name/password is entered directly by the end user.

JavaScript REST Client and session management

I've been looking around for an answer to this question, but it looks like that nobody does this. Imagine you are designing a javascript REST client, and you want to create a login page. Surely, after the login you will be authenticated.
So the following requests to the REST API will depend on your current user id, which should be stored on the client side following the RESTful way.
My question is how to store this "session" information using Javascript. I've looked into cookies, but it seems to me too much plain text for one to trust. Also using cookies one could store there an session id that maps to the user information on the server, but this violates the Stateless concept from REST.
Which the best approach to solve this problem?
We are also building similar kind of architecture where RESTful API will be accessed by a javascript client.
We will authenticate client with client credentials and generate an authentication token and that will be sent to client. Client will store it in cookie or in local data store. Further requests to API from this client will be sent using HTTP authorization header and including that token in the header. We will authorize the request at API end for the given token and request will be served once it is authenticated.
Until n unless you don't access cookie information on server side I don't think this will violate stateless principle of REST as we are not maintaining any state of the client on server (we are but not binding it to any server). Regarding the authentication process using token, I don't think we are binding the server and client here, because we have multiple servers and using load balancer and still this request may be served by any server (similar to Google api).
Note: We are doing this using HTTPS protocol so we are sure that all this communication is secured.

Categories