views:

111

answers:

3

Hey all,

Designing a fairly complicated site with a lot of ajax running on a single page. I have reached the point where some user's need to have specific permission to do things and some need to be stopped from the action. I have set up user roles in my database and all is working fine, but I wonder if there is an easier/safer method for me to store each permission.

Currently, when a user logs in their specific permissions are grabbed from the db and loaded into a session array. To check if the user has permission, I simply check to see if the permission is contained in the array. This seems sluggish, and almost like I am missing a better solution.

Also, sessions can apparently be edited by the user... is there a safer method?

I have thought running a query for each check, but that could greatly increase the load time for a simple ajax request.

I am open to any and all ideas. Thanks.

+1  A: 

Seems OK to me! You could look at some software to enhance your session chache peformance.

Querying the DB every time is not as bad as it sounds! Firstly you probably need to connect to the DB anyway, secondly if you queried the users permisions when they signed in then the chances are that all the relevent rows are sitting in the buffer and no IO is required, thirdly a query for a single permision for a single user is going to be a lot lighter than a query for all permisions for a user.

James Anderson
+5  A: 

First and foremost, the user cannot edit Session variables. The only thing that is saved on the user's machine is a Session ID. That ID is then used by the server to grab key/value pairs that are stored ONLY on the server. From a client's standpoint, it is impossible to change values on a whim.

Second, I would not worry too heavily on a database connection. Avoid repeating yourself, but don't worry too much about the first connection.

Finally, my favorite way to do multiple permissions without creating roles is to use binary math. Some people like this, some people don't, but I find it useful.

To use this method, imaging that we define the following values:

CAN_EDIT_SOMETHING        = 1     // Powers of 2
CAN_SEE_SOMETHING_ELSE    = 2
CAN_DO_ADMIN_STUFF        = 4
...                       = 8

To give people multiple permissions, use binary OR

PERMISSIONS = CAN_EDIT_SOMETHING | CAN_DO_ADMIN_STUFF

To illustrate how this works, we can look at the bits:

   0b0001
OR 0b0100
---------
   0b0101

To check if someone has a permission, use binary AND

if( PERMISSIONS & CAN_EDIT_SOMETHING != 0 ) {
}

To see how this works, we look at the bits again

    0b0101
AND 0b0001
----------
    0b0001  // Not equal to 0. They must have that permission!

The final benefit of this method is that it allows you to combine multiple permissions easily into "meta-permissions"

// If both EDIT_SOMETHING and ADMIN_STUFF are tasks that an admin
// can perform, we can combine them easily
//
IS_FULL_ADMIN     = CAN_EDIT_SOMETHING | CAN_DO_ADMIN_STUFF


// We can then use this value exactly as we do any other permission
//
PERMISSIONS       = IS_FULL_ADMIN | CAN_SEE_SOMETHING ELSE

Use it if you want, but it is a nice trick to have in your arsenal.

Stargazer712
Thanks for explaining the binary, I wanted to go with something like that when first designing roles. I ended up going with 2 db tables containing user roles and indv permissions, which makes more sense to read for me.I could also swear I saw somewhere that it was possible to pull your session data and edit it, although difficult. Maybe not.
Capt Otis
@Capt Otis, Like I said it works in some scenarios, and not in others. You know your system better than I do. As for sessions, that is how it works in PHP but you should check the system that you are using. Use Fiddler or Wireshark to examine traffic and see what it is your user is actually seeing. If all that is passed back and forth is an ID (that does not change when values change), then you are fine. If you notice more values than an ID or if you notice the session info changes when session values change, then you are in trouble and you had better look closely at your sessions :)
Stargazer712
A: 

Your explanation of the model seems a bit confused. Permission is the product of the subject authorization and the object authorization. Do you really store these products for every combination of subject and object? That's a very inefficient solution and very hard to manage.

Also, sessions can apparently be edited by the user

WTF?????!!!!

Session data should only ever be changed by the methods you define in your code - if users are able to modify any part of the session data in any way they like then this is the first problem you need to address - until you do, it will be virtually impossible to rely on any part of your authentication/authorization method unless you move authentication completely out of the domain of your application code (BTW: this is not the right way to fix the problem).

Certainly searching a very large array (not sure of the actual breakpoint - but in the region of n=1000 - but there are lots of variables affecting this) can be significantly slower than fetching the results from a database.

Its hard to say what you're doing wrong without understanding how your current system works. Is it one of these?

symcbean