December 20, 2014
Hot Topics:

Creating a Custom ACL in PHP

  • April 11, 2012
  • By Voja Janjic
  • Send Email »
  • More Articles »

An ACL (access control list) is a list that controls object permissions, determining which user can execute a certain task. It can be further extended to contain not only users, but also user groups. This is an important aspect of PHP security and is used in virtually all medium- and large-sized applications.

So, what are the advantages of an ACL model? The first advantage is security. Using this model will make your application more secure and less vulnerable to exploits. When securing any program, it is good to give to the user only the privileges he/she needs. That means that, for example, you should not give super administrator privileges to someone who will only manage website content. The ACL security model allows you to do just that. The second advantage is the easiness of user management. You can divide users into groups, while each group has certain access permissions. Also, you can easily add new user groups, delete the old ones or change group permissions.

Let's see how an ACL model works in practice. I will explain how to implement an access control list in PHP and MySQL. First, we have to create tables and their relations for users, user groups and their permissions:

CREATE TABLE users (
userid INT(10) NOT NULL AUTO_INCREMENT,
group_id INT(10) NOT NULL,
username VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
reg_date INT(10),
PRIMARY KEY(userid)
);

CREATE TABLE usergroups (
group_id INT(10) NOT NULL AUTO_INCREMENT,
group_name VARCHAR(100) NOT NULL,
PRIMARY KEY(group_id)
);

CREATE TABLE user_permissions (
pid INT(10) NOT NULL AUTO_INCREMENT,
permission_name VARCHAR(100) NOT NULL,
permission_type INT(1),
userid INT(10) NOT NULL,
PRIMARY KEY (pid)
);

CREATE TABLE group_permissions (
pid INT(10) NOT NULL AUTO_INCREMENT,
permission_name VARCHAR(100) NOT NULL,
permission_type INT(1),
group_id INT(10) NOT NULL,
PRIMARY KEY (pid)
);

The permissions tables are the most important here, as they represent a relationship between objects (users) and actions in the application. Have in mind that there are ACL security models with group permissions only. But I wanted to create a very flexible ACL, so I created both types of permissions. Now that we have the basis of this model, we need to program the dynamic part of it in PHP.

Object-oriented ACL in PHP

Before I write the code, let's mention some tips on creating a PHP object-oriented ACL. Object-oriented programming (OOP) allows you to write code more efficiently, re-using it as much as possible, while offering much better organization for the application. Regarding the ACL OOP, create your ACL as a PHP class. Use a plug-in system, or have a page which you would include in every PHP page. Also, create a class that will handle form inputs and execute ACL code upon submit. The same should be done for all AJAX requests.

So, let's create the ACL class:

<?php
Class Acl {

private $db;

//initialize the database object here
function __construct() {
$this->db = new db;
}

function check($permission,$userid,$group_id) {

//we check the user permissions first

}

}
?>

This is the class layout. The database object is initialized upon initializing the ACL class, as we have to check permissions in the database. The function check() will check the permissions and return true if the user is allowed to execute that action, or error if not allowed. Note that user permissions will be checked first, because they override group permissions. If there is no specific user permission, then we continue with checking group permissions. Also, $db is the database object, and you can use any database management class for this purpose. Look at the PHP code that checks user and group permissions:

<?php
Class Acl {

private $db;
private $user_empty = false;

//initialize the database object here
function __construct() {
$this->db = new db;
}

function check($permission,$userid,$group_id) {

//we check the user permissions first
If(!$this->user_permissions($permission,$userid)) {
return false;
}

if(!$this->group_permissions($permission,$group_id) & $this->IsUserEmpty()) {
return false;
}

return true;

}

function user_permissions($permission,$userid) {
$this->db->q("SELECT COUNT(*) AS count FROM user_permissions WHERE permission_name='$permission' AND userid='$userid' ");

$f = $this->db->f();

If($f['count']>0) {
$this->db->q("SELECT * FROM user_permissions WHERE permission_name='$permission' AND userid='$userid' ");

$f = $this->db->f();

If($f['permission_type']==0) {
return false;
}

return true;

}
$this->setUserEmpty('true');

return true;

}
function group_permissions($permission,$group_id) {
$this->db->q("SELECT COUNT(*) AS count FROM group_permissions WHERE permission_name='$permission' AND group_id='$group_id' ");

$f = $this->db->f();

if($f['count']>0) {
$this->db->q("SELECT * FROM group_permissions WHERE permission_name='$permission' AND group_id='$group_id' ");

$f = $this->db->f();

If($f['permission_type']==0) {
return false;
}

return true;

}

return true;

}


function setUserEmpty($val) {
$this->userEmpty = $val;
}

function isUserEmpty() {
return $this->userEmpty;
}


}
?>

Tags: PHP, security

Originally published on http://www.developer.com.

Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel