PHP Authentication and Access Control Libraries

Prompted by an email I got, asking for recommendations for PHP authentication and access control libraries, been trying to nail down what this kind of library needs to do. To be frank not sure I can 100% recommend an single library; I’m typically guilty of DIY – last time a really researched this, about a year and a half ago, wasn’t able to find anything that really convinced me.

From my perspective, authentication (verifying a valid user) and access control (does a valid user have permission to do this) are different things and the library needs to reflect that. Authentication usually happens before anything else at a “global” level in an application while access control can become threaded throughout everything, to the point where a menu, for example, only shows items a user is allowed to perform. User management (registration, maintenance etc) should also be separate functionality (if provided at all).

A few thoughts / requirements for a “dream” security library.

- It must be secure. Obvious I know but there’s plenty of gotchas (e.g. session files on shared web server) to watch out for. Ideally it will have had a lot of eyes looking at the source and ideally be well covered by unit tests.

- The authentication “protocol” (the mechanism between browser and web server) should be flexible allowing for different approaches; session (cookie) mechanisms, HTTP Basic and HTTP Digest should all be possible. Users should be able to use their own “plugin”, allowing them to meet their own design requirements, such as redirecting users to another page if authentication fails

- Should be independent of the data source used to authenticate a user against – database, flat files, LDAP, XML-RPC, SOAP etc. Should also allow for different “schemas” rather than being stuck to a particular column names etc. Some users way way to authentication against three fields for example; a username, a password and a some kind of temporary access code, generated from a “Smart Card”.

- Would be nice if access control logic didn’t always require hard coding i.e. instead of;


if ( $User->hasPermission('taskName') ) {
// Do the task
} else {
echo 'Permission denied';
}

…you could (optionally) use some other mechanism for access control, e.g. a .ini file with the same name as the PHP script or perhaps something based on the URL. Perhaps something similar to the Unix filesystem permissions would be helpful here.

- Allows for different access control “organisation” – e.g.
user <=> permissions
user <=> role / group <=> permissions

- Flexibility: should work with any PHP coding style, from vanilla PHP to frameworks

- How do the authentication and access control mechanisms communicate.

- Fast (of course) – despite all the functionality it’s packing, you only pay the price for what you’re using

Any other requirements for an ideal security library?

If I was going to recommend something, it would have to a library from PEAR. There’s a number of packages in the Authentication category, the two which are most relevant to this discussion being;

- PEAR::Auth – focuses on authentication only. Hits the target of being able to authentication against multiple data sources, using a username / password combination. Uses sessions / forms to maintain state. Extended by PEAR::Auth_HTTP for HTTP Basic / Digest authentication. Gets a lot of screening which is good news. Performance? For some reason I can’t remember now, I’ve always been biased against PEAR::Auth, perhaps because I looked at an early release. Looking at the code know it seems generally a reasonable choice.

- PEAR::LiveUser – provides authentication and access control. Users sessions to maintain state and is able to handle a number of different access control organisational schemes. I’ve tried this before and struggled to make sense of it’s intended use but it is work in progress and has a lot of promise.

Any other libraries you recommend?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • sevengraff

    I am suprised you didn’t metion phpGACL (http://phpgacl.sourceforge.net/). It’s an impressive library that that allows for some of the things you listed.

  • http://www.phppatterns.com HarryF

    Thanks for the tip off.

    Like I say the last time I really went looking was ages ago. PHPGACL has blipped on the radar once or twice but never looked at it. Guess now’s the time… ;)

  • Dangermouse

    No non-pear packages?

  • http://www.phppatterns.com HarryF

    No non-pear packages?

    Anything you like to recommend, feel free. I just named those two as I have a rough idea of them.

  • http://www.php-tools.de schst
  • Martin Jansen

    The Horde folks have a fine authentication system in their framework as well (http://cvs.horde.org/browse.php/framework/Auth/).

    P.S. The “official” URL for referring to PEAR packages is http://pear.php.net/package/Foo, not http://pear.php.net/Foo. (Both work fine though.)

  • http://www.sample.com Widow Maker

    Martin, thanks for the link to the Horde framework :)

    Have you (personally) used this before, as looking over the various classes briefly, it looks like it can do some real damage to the time it takes to develop applications, lol

  • Markus Wolff

    Actually, most of what you described above actually describes what LiveUser does quite well ;-)

    - It has pluggable Authentication modules (not many yet, but there also is a wrapper around PEAR::Auth available so you can leverage all its containers as well).

    - It has pluggable Authorization containers, meaning you could implement any kind of permission management that fits your need and use it with LiveUser, as long as you stick to the LiveUser container API.

    - It already comes with several permission management containers that are interoperable, but reflect different levels of complexity. Once your website grows and needs more complex permission management, just switch the container to the next more complex container and it will work – without touching any of your code

    - You can either assign rights directly to users or to user groups. You can also revoke certain rights for individual users even though they would normally have then through group memberships

    The only thing you mentioned that is not yet there is role-based permission management, because for a long time the developers (including me) thought that this can easily be achieved using groups as well – but since the users didn’t seem to see it like we do, “roles” will be implemented soon as well.

    If you’re interested in the roadmap, there’s now a wiki at:

    http://pear.limbourg.com/

    Regards,
    Markus

  • David C

    I’ve never used any of these specific packages, but I’d like to second Harry’s idea about not hardcoding “hasPermission()” values.

    I haven’t finished working out what I’m going to do, but I think that I’ll have each module in my application have a getPermissions() method, which the ModuleLoader checks. getPermissions() will probably return an array with $_GET['do'] => ‘permission’ — that way the ModuleLoader can itself do the authentication and security problems rarely slip through the cracks. It also allows for a certain degree of abstraction.

    Hope that helps!

  • Lukas

    ‘not hardcoding “hasPermission()” values’

    Could you guys elaborate what you really want here. Are you talking about RBAC style permissions? That are implemented in generic methods that know which right to check for based on the module that has called the generic method?

    like a generic getTemplate() method that knows the module that called it and thereby knows what right to check?

    If that is what you mean then its possible with LiveUser using a right area per module.

  • Jimmy Lantz

    I feel that you have missed out on a simple but good Auth module. http://oss.codepoet.no/phpsecuresite/ PHPss has lots of potential. just my 2 cents :D

  • http://www.phppatterns.com HarryF

    ‘not hardcoding “hasPermission()” values’

    Could you guys elaborate what you really want here.

    My own thought was there’s many different ways people might want to do this.

    Although hard coding should be possible, other approaches that come to mind include;

    - Using external configuration files placed alongside PHP scripts, which define what “security clearance” a user need for the actions they can perform which that script

    - Having a system which controls access to class methods e.g. checks that a given user is allowed to execute Article::edit()

    Not saying the library needs to support this natively but rather it should be possible to use it in different ways.

    Think I need to take another look at LiveUser, particularily following Markus’s comments. Last time I looked it was version 0.9 I believe and was under time pressure to deliver so probably didn’t give it long enough.

  • Lukas

    Ok both things are possible.

    The trick is that we have a “define_name” field for every ID that can may need to be referenced:
    applications
    areas
    rights
    groups
    (languages)

    You can export these as constants, as an area or you can search for the id at runtime.

    By being able to organize areas into applications and rights into areas you have all the metadata you need to be able to do all of the above.

  • IpSo

    *DISCLAIMER: I’m the author of phpGACL*

    You guys bring up some interesting ideas, but I think you may find that they may not be practical in practice. For instance:

    “- Using external configuration files placed alongside PHP scripts, which define what “security clearance” a user need for the actions they can perform which that script”

    “- Having a system which controls access to class methods e.g. checks that a given user is allowed to execute Article::edit()”

    Both ideas would probably work quite well for very basic applications. However I think you would find they fall flat on their face for any application with complexity involved. This is one of the reasons I started phpGACL, I was tired of all the pre-built permission systems that only went “half way”.

    For instance, you don’t want to show a “Edit” or “Add” link to a user when they don’t have permissions to use it. You want remove that link from displaying as well as check permissions if someone were to bookmark the direct “edit” link. Thats not always easy to do with a seperate permission configuration file, and having to call Article::Edit() to see if they have access isn’t exactly efficient. It also gets even more complex when you want to allow specific users, or groups of users access to this “Edit” link. Or only people who created the object to edit it.

    If your looking for a flexible AND a fast permission system, I would be very interested if you could find one that beats phpGACL. It uses a SQL Modified Preorder Tree Traversal (MPTT) method that is proven to be one of the fastest ways to do tree lookups in SQL, (useful for group inheritance of course) combined with the fastest available PHP caching system and on demand cache invalidation. So ACL checks really only need to hit your database once every time you edit the ACL.

    Enjoy. ;)

  • CT

    Ultimately the Permissions are “hard coded” somewhere. I think Harry is right that there are several different ways to do it, each one suited to a different architecture. Frameworks might provide built-in support or let a module deal with it.

    For me the practical problem with built-in support is that for a typical website things like administrative pages are very lightly accessed, whereas the most accessed pages often do not require any access control but would still have the code overhead for built-in access control.

    For more monolithic scripts, Harry is right, there needs to be access control at the funciton/method level. And don’t forget a CMS type system where the access control is at the record level.

    Harry, do you (or anyone else) have any thoughts on what a base class to support these different types of access control classes might look like? What do all the ones you looked at have in common? Obviously the access check itself is common (and hopefully allows plug-ins), but for example loading a external access list and looking up the page’s access controls would be an extension. And how does each file/class/funciton/record identify itself?

  • wasp

    The Mambo 4.6 and 5.0 CMS versions currently under development on mamboForge.net fully embrace MPTT and the use of phpGACL AXO groups to implement granular authentication on sites, modular elements (components, modules, and plugins) and content using a groups/roles based methaphor. One only needs to look into CVS to view the experimentation going on. The phpGACL AXO groups are being used extensively to categorize all object and methods thoughout the class hierarchy. Portions of the 5.0 code are gradually moving into the 4.6 version where MPTT is being implemented. The use of MPTT fits in well with the alternate tree traversal methods suggested for the W3C DOM recommedation.

    Based on the Mambo 5.0 Roadmap documentation, it would appear that the MPTT model drifts upward into the network topology of sites planned for their RAMBO concept where secure sitekey identifiers are used to allow Mambo sites to communicate securely across multiple webservers using XML-RPC technology.

    The Mambo development team is well know for using different approaches at the core level to overcome development obstacles. Monitoring and watching this particular project come together over the poast few months has been food for much thought and resulting ideas.

  • Carry2Web

    Thank you wasp for insight in the Mambo developments regarding user and groups/roles enhancements!

  • agentolivia

    Just because I keep coming back to this post for ideas for authentication and access control (maybe others do too??), I thought I’d post this article from evolt that I just discovered, published Sept 24, 2004.

    PHP Login System with Admin Features:
    http://www.evolt.org/article/PHP_Login_System_with_Admin_Features/17/60384/index.html

  • Russell

    agentolivia – thanks for the link – I have come back here on a number of occasions researching authentication and have never settled on a solution that was right for me. I followed your link and it so far it seems to be exactly what I was looking for. Cheers!

  • DarkPilgrim

    I think I’d like to use phpGACL. agentolivia’s link “was” great(but out of date).