I work at a small consultancy and we often make web apps for our clients. One part of the web app that is often repetitive to write is the authentication system. In a lot of our web apps we would like to support OAuth login from the various providers as well as email-based registration.
However, programming this in every web application is time-consuming. Ideally what we'd like is a generic, authentication proxy server that sits in front of the application server and handles everything related to authentication (including login, registration, and logout). I'm wondering if something like this would be secure? Or if there is any security-related reason why it should not be done like this?
I'm imagining it would look like this:
- This is basically a reverse proxy server. It has its own database with information related to authentication (for example, email address, password, etc).
- It checks each request for a specific cookie with session information (for example, a JWT in a cookie called
SESSION). This session information would be proof that the user has logged in correctly at some point in the past. If the session information is correct, it adds an
X-UserIdheader to the request and forwards it to the Application Server. If there is no cookie with authentication information, or if the session information is incorrect, then it forwards the request to the application server without the
- It will have specific routes for logging-in, logging-out, and registration (for example,
/register). It will handle these requests completely on it's own. The Application Server will not even be aware of these requests.
- This is a normal web application server.
- It performs no authentication, relying entirely on the
X-UserIdheader from the Auth Server.
- It is not accessible from the outside world. The only way to access it is by going through the Auth Server.
- It also has its own database. It is filled with all the information related to the application (except for authentication information).
Here is an example of how login could work, as well as the interaction between the Auth Server and Application Server:
Here are the steps for getting the
- The client sends a request for
- The Auth Server receives the request. The Auth Server tries to look for a cookie called
SESSION. It doesn't exist, so it forwards the request to the Application Server without adding a
- The Application Server receives the request. There is a route defined for
/login.htmland it doesn't require the
X-UserIdheader to exist, so it returns the HTML for
- The Authentication Sever receives the response, and forwards it back to the user.
login.html page could contain the JS code for actually logging in. Here is one possible way to do it.
- The client sends an AJAX request to
/login/emailto login using an email address and password.
- The Auth Server receives the request. Since this is a request for the Auth Server, it does not forward the request to the Application Server.
- The Auth Server looks at the request body for an email address and password. It checks the email address and password in its Auth DB.
- If the email address and password are correct, it returns an
SESSIONthat contains a JWT.
After this succeeds, the user could be directed to
/home.html. The steps for this are similar to
/login.html, except that the user is actually required to be authenticated:
- The user sends a request to
- The Auth Server receives the request. The Auth Server checks the
SESSIONcookie and decodes the JWT. The Auth Server gets the User Id from the database based on the information in the JWT. Let's say that the User Id is 5.
- The Auth Server adds a
X-UserId=5header to the request and forwards it to the Application Server. (In the case where the
SESSIONcookie doesn't exist, or the JWT is not able to be successfully decoded, the Auth Server will forward the request to the Application Server without adding a
X-UserIdheader. The following steps are written assuming that the authentication succeeds and the Auth Server adds the `X-UserId header.)
- The Application Server receives the request. Since the request is for
/home.html, the Application Server knows that a valid User Id is required, so it checks the
- The Application Server successfully gets the User Id from the
X-UserIdheader and uses it to pull data out of the Application DB and build the
- The Application Server sends the response with the
home.htmlpage to the Auth Server.
- The Auth Server receives the response, and forwards it back to the User.
Here is some additional information that didn't really fit above:
- The Auth Server would remove the
X-UserIdheader if sent by a user before forwarding the request to the Application Server.
- The Auth Server could be relatively general, and used on multiple different projects. The Application Server wouldn't have to worry at all about authentication.
- The Application Server would need to be in charge of authorization (for example, making sure that each user could only edit their own information).
- The Auth Server would completely handle new user registration. This could include an OAuth flow (for using OAuth as provided by Google, Twitter, Facebook, etc), as well as simple email-based registration. When a new user registers, the Auth Server would create a User Id and link it to the user's email address, Google username, Twitter username, etc. The Application Server would only ever see this User Id (never the user's email address, Google username, Twitter username, etc).
Is a setup like this secure?