arch bash cakephp dauth devops drupal fosdem foss git golang information age linux lua mail monitoring music n900 netlog openstack php productivity python real life thesis travel uzbl vimeo web2.0

Figuring out CakePHP's new AuthComponent

In the Cake community, there has always been much interest in authentication/authorization systems. The issue of authentication has been addressed in several add-ons provided by the community, such as DAuth (written by me), OthAuth (written by Crazylegs) and many others.

However, one of the additions to the 1.2 branch which is currently in active development , is a built-in auth module. A module that isn't finished yet but it sure is worth it looking at. (In fact I'm thinking about making a new dAuth version built on cake's own auth system.). As most bakers know, there is very little information about the 1.2 branch in general, and the auth component in specific. So what I will try to do, is delve in the code, mess with it, and explain my findings in this post. For this first post it will be more trying to decipher the source code, messing with it will probably for a little later on.
Disclaimer: not everything I'll say here will be correct, first of all because I'm not able to fully understand every piece of the source code (yet), secondly because the 1.2 api is still changing.

The version i use for this post is svn head. (revision 4758 at time of writing)

The header

So let's just open cake/libs/controller/components/auth.php.
Reading the first comment we immediately see "Manages user logins and permissions." This looks very important to me. Seems like this component handles both authentication and access control. It seems like the AuthComponent is able to interact with the ACL system that we know from the 1.1 branch. Multiple uses of the AclComponent ($this->Acl inside the component) confirm this.

Member variables

The AuthComponent has quite some member variables, the most important ones seem to me:

  • $userModel (aro's) & $objectModel (aco's)
  • $loginAction: url for login action, null by default but we should set this (to something like 'users/login') when we want to use the component in our application. As usual AppController's beforeFilter() seems like a good place for that.
  • $validate: set to 'actions' or 'objects', depending on what you want to check the access for. Actually there are more options, read on. However: on first sight it seems like combinations of objects-actions aren't possible...Anyone knows more about this?
  • $_loggedIn: true/false
  • $allowedActions: no user validation on these actions

Functions

Now, let's move on to the available functions (the most important ones that is) ...

  • initialize(&$controller) seems to be a new ( in 1.2) callback.
    Dispatcher calls $controller->_initComponents(), which (controller.php) in turn calls $component->init($this), which calls $tempComponent->initialize($controller).
    So this function is called automatically, and when that happens $controller->params are all copied to $this->params (by value). Some more stuff happens but I don't think it's very important at this time.
  • The startup(&$controller) callback is familiar to 1.1 users. It is called in the startup-phase of the component, shortly after the initialize callback. What happens here?
    • The password in $controller->data is hashed by using a call to "Security::hash(CAKE_SESSION_STRING . $password)". (called via $this->hashPasswords() which calls $this->password().
      After that $this->data = $controller->data;
    • A check whether ($this->allowedActions == array('*') || in_array($controller->action, $this->allowedActions)).
      In this case no further processing is needed: access is granted, i don't know why we return false here, though
    • Then we have 2 cases:
      Either we are at the login action (defined by $loginAction like mentioned earlier), or we are somewhere else. I think it will be clear what happens when you study the code, but I do think it's important to mention that the actual login happens at line 274 ($this->login($data), function definition at 470).
      The identify function at line 624 is important too. I guess this one checks the credentials.
      If we are somewhere else then $loginAction, access is checked at line 293 (function isAuthorized(), function definition at 332.
      Inside this function, $validate is assigned to $type, so it seems like not only 'actions' and 'objects' are valid values, but also 'association' and 'controller'. I don't really get why this is made so complicated (the __authType() step for example.).
  • Another callback new in 1.2 is shutdown(&$controller). Unlike initialize, this one is mentioned on Nate's blog. It removes 'Auth.redirect' from the session when the user is logged in.

Conclusion

This was only a slight introduction, more research (and thus explanations) will happen later on and you can also expect some sample code. Give me some time though ;-)

Comments

Hi, just stopped by to write "Thank you for your effort" and awaiting further research and ultimately the new dAuth:)

Hey Dieter, thanks for breaking this down. Do you think the API is set and the functionality is solid enoguh to use? I would love to use it, but if they are just going to change the interface on me in a month then I don't want to use it.

@Tarique: you're welcome :-)

@rtconner, that's always a guess... Even the cake team itself can't be sure how it will evolve, although off course they'll have a better view on it then us, so I'll ask the guys if they want to read our questions and reply to them.

When I think about authentication, I find features like these a must: challenge response (passwords being sent over a network, hashed according to al algorithm that changes all the time), a configurable fall back , brute force (hammering) detection and blocking, user configurable hashing (some want md5 (although md5 is weak), others like sha1, or others, or combinations of them), session hijacking protection (cake already does quite a bit in that area, but imho afaik not everything required for a secure auth system, you'll find more about that in the DAuth article),...
So, those features are the one I implemented in DAuth. Probably I mix auth-system specific aspects with application-specific ones. I have learned a lot by checking code from the cake team and often thinking "hey this is a better approach to structure this functionality". Also, some of the stuff DAuth has, becomes obsolete when https (SSL) is available. On the other hand, on my DAuth todo list are features that are behavior you would get by using https, but I want to offer them to those who have no https available, and want to be secure.

So, 2 things i wonder: (just like you)
1) how drastically will the API change? (not too much I think but you never know)
2) which features from my list will be implemented, and especially where? And also, how (and especially where) do we write our own logic if we want certain features that aren't available in cake's AuthComponent. Would this even be good practice? I think yes because I think features like the ones mentioned above are critical for security, but I can imagine the cake guys don't agree with the way DAuth (and other systems) are built and have much advice for us in that area.

Thank you very much!

you're welcome \o/

Hey Dieter !!

As I've been way to much involved in my new job here in the UK I haven't had any time to catch up on the new features in 1.2.

First it's quite refreshing that this is getting into the core !!!

Second, many thanks for the breakdown since I'm gonna start a project based on 1.2 and was wondering if all my investigation around ACL and AUTH was to 1.1 centric and would have to recode the whole bunch of examples I've collected.

Second I would like to leave the link to some code someone posted on the ML:
Auth component + Cake 1.2

Cheers,
Gustavo Carreno aka [Batch]

auth has to change in the startup fun.

i found the block if(this->authorize) has to change to
if(!this->authorize)
for things to work fine

:P
really cake

this will disable the acl from being checked.


Name:


E-mail:


URL:


Comment:


What is the first name of the guy blogging here?


This comment form is pretty crude. Make sure mandatory fields are entered correctly.
Basic html tags (a,i,b, etc) are allowed, others are sanitized