How to do: Group Based Authentication and Authorization
Someone on The List asked how to setup what they called “Multi-level login security”. Many Content Management Systems these days have this very feature. They will have a few people who are Administrators and can access everything on the site, another group of people who are editors who can only access a few things and then you have authors who can only submit stories and edit their own stories. In addition, this type of security needs to allow uses to be moved from group to group while keeping this totally transparent to the user. The question is though, how do you set this up on your site? This is actually not that hard to do. It takes three database tables and a little bit of forethought. We will start with the theory behind this simple technique, move on to the database tables, and end with a simple way of implementing this on a web site.
To begin with, in order to implement this, you need to put some separation between a user and what they can access. This is done by creating groups and then assigning a user to one or more groups, depending on what you want that user to be able to do on the site. For this article we will use the ones mentioned above, namely Admin, Editor, and Author.
Once you have your groups, you need to decide which parts of your site can be access by each group. Obviously, an administrator can access everything while an author can only submit stories. While an editor can access an authors submitted story before it is published. Each part of your site needs to be assigned to a Group. Just remember this for now, we will discuss how to do it a little later. First, let’s discuss how to set up our groups and users in a database.
If you remember, the idea behind this is to separate the users from the groups that they belong to. This is done by creating three tables in a database. One table to hold the users, one table to hold the groups, and the last table to assign a user to a group. Here are what the tables might look like:
User +--------+----------+----------+ | userID | username | password | +--------+----------+----------+ | 1 | foo | bar | +--------+----------+----------+
Groups +---------+----------+-------------+ | groupID | group | description | +---------+----------+-------------+ | 1 | admin | | | 2 | editor | | | 3 | author | | +---------+----------+-------------+
User_Groups +--------+-------+ | userID | group | +--------+-------+ | 1 | 2 | | 1 | 3 | +--------+-------+
As you can see from the tables above, this setup allows a user to belong to more than one group. This is what allows a user to progress through positions on the site. A user can start as an author and then move up to an editor while still retaining all the abilities of being an author. In addition, it allow you to isolate a user as an editor. This would mean, in our little example, that that user could access and edit stories, but they would not be able to submit any of their own. For complicated sites, this can be an advantage.
Now that you have your users and groups all setup in the database, how do you translate this to the rest of your site?
First, you need to have your users login to your website. When they login, you check their username and password against the database. If they are a valid user, you then retrieve the list of groups that they belong to. This is the important part. You need to place that list of groups into a session variable that will be accessible from every page on your site. For security reasons, you don’t really want to store this kind of information in a cookie as it is too accessible to a malicious user. Therefore, to implement this, you need to pick a language that supports user sessions.
Now that you have the list of groups a user belongs to, how do you enforce this against pages on your site? There are many different ways of doing this depending on how your site is setup and what kind of information you need to restrict. I am simply going to illustrate this by making it so that all that needs to be restricted is access to individual pages.
The easiest way to enforce your groups is to assign each page (or group of pages, depending on their functionality) to a group. So for the author, all the pages that work together to allow an author to submit a story would be assigned to the author group. On a praticle level, this can be as simple as setting a variable at the top of your page. This is how you would do this in php:
< %php $group = "author" %>
Once the variable is set, you need to validate your user against that group. How you do this will depend on how you implement your list of groups that a user belongs to. Different languages will have different ways of handling lists and searching for elements in a list. But basically, all you want to see is if the value of the group variable matches an element in the users list of groups. If it does, the user belongs to the same group as the page and is able to access that page. If a match can not be found, then you can redirect the user to an error page or back to the homepage.
This is the most robust method of authentication and authorization that I have come across so far. And it is fairly easy to implement. So if you are looking for a method of restricting different parts of your site to different kinds of users, give this a try. You will quickly see the advantages that it holds.