phpcakephpcakephp-2.0

Authorized public URL keeps redirecting for authentication and failing


In this scenario, OurCustomAuth is currently returning an expected value of false, is reaching the appropriate else, but the users/error path keeps redirecting even though it's been made public and not requiring any authentication.

I've setup the new action:

C:\wamp\myapp\app>Console\cake AclExtras.AclExtras aco_update

Welcome to CakePHP v2.4.9 Console
---------------------------------------------------------------
App : app
Path: C:\wamp\myapp\app\
---------------------------------------------------------------
Created Aco node: controllers/Users/error
Aco Update Complete

In the UsersController, I've added the action to be made public:

public function beforeFilter() {
    parent::beforeFilter ();
    $this->Auth->allow ('logout', 'error');
}

In AppController, the Auth config:

public $components = array(
    'Acl',
    'Cookie',
    'DebugKit.Toolbar', 'Session',
    'Auth' => array(
        'authenticate' => array('OurCustomAuth'),
        'loginAction' => array('controller' => 'users', 'action' => 'view'),
        'authError' => 'Did you really think you are allowed to see that?',
        'authorize' => array('Actions' => array('actionPath' => 'controllers'))
    )
);

...
public function beforeFilter() {
    ...

    //Auto logging users in if they are not logged in
    if (!AuthComponent::user('id')) {

        if ($this->Auth->login()) {

            //stuff here

        } else {
            $this->Session->setFlash(__('We could not authenticate you ...'));
            return $this->redirect(array('controller' => 'Users', 'action' => 'error'));
        }
    }

    ...
}

The error I get in Firefox:

The page isn’t redirecting properly

Firefox has detected that the server is redirecting the request for this address in a way that will never complete.

Update #1

$this->Auth->login() essentially grabs request headers, that in this case are intentionally wrong, which seems to redirect to the appropriate link. However, /users/error shouldn't cause a redirect as it's excluded from Authentication.


Solution

  • The problem is that you run your login code on every request, ie in the app controllers beforeFilter() method. So when that code redirects you to /users/error because you're not logged in, the code will run again for that controller/action, and redirect you again, and again, and again...

    If you need to run this code for every request, then you'll have to check the allowed actions manually, ie the actions allowed via $this->Auth->allow(), and run your code only in case the current action isn't allowed. Check the code of AuthComponent::_isAllowed(), you can easily use that with minimal modifications:

    $action = strtolower($this->request->params['action']);
    if (!in_array($action, array_map('strtolower', $this->Auth->allowedActions))) {
        //Auto logging users in if they are not logged in
        if (!AuthComponent::user('id')) {
            // ...
        }
    }