I wrote this in PHP but you can use the same concept in other languages, I also assume an understanding of bits, bytes, binary to decimal conversion and vice-versa and bitwise operations on numbers like ‘or’, ‘and’ and ‘xor’ etc. if you have no idea, search and read about these first. You don’t have to be a guru but you should have an idea. Here are some pages to get you started:
http://en.wikipedia.org/wiki/Byte
http://en.wikipedia.org/wiki/Bitwise_operation
http://us.php.net/manual/en/language.operators.bitwise.php
Some binary to decimal calculators to make it easier
We will use simple numbers to represent different permissions and as you might know a number is a collection of bytes. For example: an integer is usually 4 bytes. Although you don’t have to worry about the size of a number in a high level language like PHP but a little understanding of representation of numbers will help you better understand this technique.
So let’s assume when I say:
<?php $user_perms = 7; ?>
Internally the variable $user_perms looks like this:
|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|1|
This is a 2 byte representation of number 7, although, it might not look like this internally – it looks similar. Just assume this for now.
Let’s say that your application supports 4 functions that a user can use:
1 – Post a blog post
2 – Comment on blog posts
3 – Edit posts
4 – Delete posts
Normally, you could have 4 fields in your database table (structure or whatever) for a user titled:
1 – can_post
2 – can_comment
3 – can_edit
4 – can_delete
This is not good, 4 additional fields for your user table and who knows, what if your application has 100 functions? Do you want to add 100 fields to your user table?
With bits, you can have only 1 column and track all the permissions.
1 – perms
To do this, we will have to assign numbers for each of the functions: (Tip: use one of the calculators in the above list
)
1 – Post a blog post |0|0|0|0|0|0|0|1| is 1 in decimal
2 – Comment on blog posts |0|0|0|0|0|0|1|0| is 2 in decimal
3 – Edit posts |0|0|0|0|0|1|0|0| is 4 in decimal
4 – Delete posts |0|0|0|0|1|0|0|0| is 8 in decimal
So you could have an array like this:
<?php $perms = array( 'can_post' => 1, 'can_comment' => 2, 'can_edit' => 4, 'can_delete' => 8 ); ?>
Almost there, let’s look at user’s perms field now.
I hope you know about bitwise ‘or’, when you ‘or’ 1 and 1 you get 1; 0 ‘or’ 1 is 1; 1 ‘or’ 0, is 1 and finally 0 ‘or’ 0 is 0, it’s just like the meaning of ‘or’ in the English language.
Similarly, bitwise ‘and’; when you ‘and’ 1 and 1 you get 1; 0 ‘and’ 1 is 0; 1 ‘and’ 0, is 0 and finally 0 ‘and’ 0 is 0, again it’s just like the meaning of ‘or’ in the English language.
Bitwise ‘xor’; when you ‘xor’ 1 and 1 you get 0; 0 ‘xor’ 1 is 1; 1 ‘xor’ 0, is 1 and finally 0 ‘xor’ 0 is 0.
So suppose you want to give a user permissions to post a blog post, post a comment and edit posts but not delete posts, you do it like this:
<?php $user_perms = $perms['can_post'] | $perms['can_comment'] | $perms['can_edit']; ?>
Note that, in PHP ‘|’ means ‘or’, so what just happened is something like this:
|0|0|0|0|0|0|0|1| ‘or’
|0|0|0|0|0|0|1|0| ‘or’
|0|0|0|0|0|1|0|0|
_______________________
|0|0|0|0|0|1|1|1|
Now $user_perms has the value 7 and |0|0|0|0|0|1|1|1| in it internally.
Suppose that this is on top of your post_blog.php or where ever you want to handle permissions for posting a blog, the only thing you need to do is:
<?php if ($user_perms & $perms['can_post']) { /* He/She has permissios to do this */ } else { /* He/She doesn't */ } ?>
In PHP ‘&’ is for bitwise ‘and’, please also note that ‘&&’ is logical ‘and’ and doesn’t operate on individual bits.
This is exactly what just happened:
|0|0|0|0|0|1|1|1| ‘and’
|0|0|0|0|0|0|0|1|
_______________________
|0|0|0|0|0|0|0|1|
So that’s ‘one’ not ’0′, which means ‘if’ passes and the user has permissions to do this. But when it comes to deleting posts:
<?php if ($user_perms & $perms['can_delete']) { /* He/She does permissios to do this */ } else { /* He/She doesn't */ } ?>
Thus:
|0|0|0|0|0|1|1|1| ‘and’
|0|0|0|0|1|0|0|0|
_______________________
|0|0|0|0|0|0|0|0|
It’s ‘zero’ so ‘if’ fails and you show an error message or whatever it is you do.
To add ‘delete’ permissions, you use ‘or’ again:
<?php $user_perms |= $perms['can_delete']; ?>
So this happens:
|0|0|0|0|0|1|1|1| ‘or’
|0|0|0|0|1|0|0|0|
_______________________
|0|0|0|0|1|1|1|1|
To take away permissions you use ‘xor’:
<?php $user_perms ^= $perms['can_delete']; ?>
And this will happen:
|0|0|0|0|1|1|1|1| ‘xor’
|0|0|0|0|1|0|0|0|
_______________________
|0|0|0|0|0|1|1|1|
And delete permissions are gone!
Now let’s take away post permissions:
<?php $user_perms ^= $perms['can_post']; ?>
Thus:
|0|0|0|0|0|1|1|1| ‘xor’
|0|0|0|0|0|0|0|1|
_______________________
|0|0|0|0|0|1|1|0|
So this was just the basics, you can build on this and do more once you understand.
I hope this post will help someone
I'm the co-founder of
Nice article, but does it mean that if you fix it this way, that you can only have 32 rights on a 32bit system and 64 rights on a 64bit system?
Or does it work in another way?
Comment
Yes, that is technically correct, so you could have permission groups maybe…
I would assume 32 bits though, since you don’t know where your code is going to run.
Comment
I understand that..
I asked it because I want to write a ACL class of my own.
And bitwise is the easiest solution in this case. The bit limit is something I don’t like though
Comment
If you have to track more that 32 permissions then you could have permission groups I guess…
Comment
Thanks! This is a great help for me!! Good job!
Comment
Fist of all it is a great example page to demonstrate the use of bitwise operators, but… implementing the example permission system this way is not as much flexible as it couud be in sql
users (userid PK, etc…)
permissiontypes (permid PK, etc)
user_permission(userid FK, permissiontype FK)
You would have much easier code on the long rin and implementing the mentioned group (role) based authentication is a breeze.
And yes, of course it is way better to wrap it with a permission class if you ever have to use a standard user/permission repository for example by LDAP.
Comment
Do you mean keeping permissions in a database so you are not hard coding it?!
If that’s what you mean, it’s OK to do it that way in situations where you need it otherwise you should always keep it simple…
Of course, permissions for each individual user should be kept in the database.
Comment
Thanks for the great article.
Can we use the similar approach to design the field/object level security and plug this with the customized security manager ?
Comment
I’m not exactly understanding your question but if you mean what I think you mean then yes…
Comment
Thanks for the quick repoly.
Infact i wanted to design a customized security module which can work on fields level. meaning every field in my application can have enable/diable/visible flags that can be configured for each user/group.
The idea is to use same technique (bitwise operators) which will eliminate defining hundereds of fields in my database and i will only define a few integer values for each user and screen combination.
I have tried to simulate the same with the provided example, it worked but the real problem now is the 32 bit nature of Int in C# cannot possibly go beyond 32 fields at most.
Any better thoughts for moving forward.
Comment