title: CakePHP 2.3.2 BasicAuthentication not working
body: <p>I tried out the "Simple Acl controlled Application 1&amp;2" tutorial located at <a href="http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html" rel="nofollow">http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html</a> .</p>
  
  <p>After doing this, I tried to activate BasicAuth instead of FormAuth.</p>
  
  <p>I reimplemented the login() function im my UsersController as follows:</p>
  
  <pre><code>public function login() {
  if ($this-&gt;Auth-&gt;login()) {
          return $this-&gt;redirect($this-&gt;Auth-&gt;redirect());
      } else {
          $this-&gt;Session-&gt;setFlash('Not able to login');
      }
  }
  </code></pre>
  
  <p>and changed the $components variable in my AppController to the following:</p>
  
  <pre><code>public $components = array(
      'Acl',
      'Auth' =&gt; array(
          'authorize' =&gt; array(
              'Actions' =&gt; array('actionPath' =&gt; 'controllers')
          ),
          'authenticate' =&gt; array('Basic')
      ),
      'DebugKit.Toolbar',
      'Session'
  );
  </code></pre>
  
  <p>The BasicAuth "popup" appears as expected, but when I'm trying to login, it reappers in an endless loop. I did not change anything after doing the tutorial except for including DebugKit.</p>
  
  <p>What am I missing? I hope someone can help me, as I'd like to go with CakePHP coding my next Project!</p>
  
  <p><strong>Update</strong></p>
  
  <p>AppController</p>
  
  <pre><code>public function beforeFilter() {
      //Configure AuthComponent
      $this-&gt;Auth-&gt;allow('display');
      $this-&gt;Auth-&gt;loginAction = array('controller' =&gt; 'users', 'action' =&gt; 'login');
      $this-&gt;Auth-&gt;logoutRedirect = array('controller' =&gt; 'users', 'action' =&gt; 'login');
      $this-&gt;Auth-&gt;loginRedirect = array('controller' =&gt; 'posts', 'action' =&gt; 'add');
  }
  </code></pre>
  
  <p>UsersController</p>
  
  <pre><code>public function beforeFilter() {
      parent::beforeFilter();
  }
  </code></pre>
  
  <p>I'm trying to access e.g. <code>/users/</code> which works like a charm using the FormAuth described in the tutorial, so there can't be a permission problem. Logindata is pretty simple for testing (admin:admin) so there should be no problem either.</p>
  
  <p><strong>Update 2</strong></p>
  
  <p>In my Apache Log i get the following, so it says I'm not authorized:</p>
  
  <blockquote>
    <p>IP - - [16/Apr/2013:18:08:37 +0200] "GET /users/login HTTP/1.0" 401 5179 "-" "Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:23.0) Gecko/20130414 Firefox/23.0"</p>
  </blockquote>
  
  <p><strong>Update 3</strong></p>
  
  <p>For some reason it seems, that User and Password are either not sent or not saved in PHP. If I rewrite <code>/lif/Cake/Controller/Auth/BasicAuthenticate</code> to the following, it works!</p>
  
  <pre><code>public function authenticate(CakeRequest $request, CakeResponse $response) {
      $_SERVER['PHP_AUTH_USER'] = $_SERVER['PHP_AUTH_PW'] = "admin";
      $result = $this-&gt;getUser($request);
  
      if (empty($result)) {
          $response-&gt;header($this-&gt;loginHeaders());
          $response-&gt;statusCode(401);
          $response-&gt;send();
          return false;
      }
      return $result;
  }
  </code></pre>
  
  <p><strong>Update 4</strong></p>
  
  <p>Don't know if thats helpful, but the Server is running Plesk 11, latest update, no special modifications.</p>
  
  <p><strong>Update 5</strong></p>
  
  <p>Okay, that answer of "thaJeztah" was useful, but now I'm getting more problems which can be subdivided.</p>
  
  <ol>
  <li><p>Changed mode from fcgid to apache module</p>
  
  <p>1.1. Results in working login, but logout does not work! After the redirect, the session seems to be cleared, but i can still access every restricted page until i clear my browsers "Active Logins" as it is called in Firefox.</p></li>
  </ol>
  
  <blockquote>
  <pre><code>var_dump($this-&gt;Session-&gt;read('Auth.User'));
  
  NULL
  </code></pre>
  </blockquote>
  
  <p>When I access /users/login I am automatically logged in and redirected without having to enter login credentials.</p>
  
  <blockquote>
  <pre><code>print "&lt;pre&gt;";
  print_r($this-&gt;Session-&gt;read('Auth.User'));
  print "&lt;/pre&gt;";
  
  Array
  (
      [id] =&gt; 1
      [username] =&gt; admin
      [group_id] =&gt; 1
      [created] =&gt; 2013-04-12 12:54:26
      [modified] =&gt; 2013-04-16 14:27:24
      [is_active] =&gt; 1
      [Group] =&gt; Array
          (
              [id] =&gt; 1
              [name] =&gt; Admin
              [created] =&gt; 2013-04-12 12:46:42
              [modified] =&gt; 2013-04-12 12:46:42
          )
  
  )
  </code></pre>
  </blockquote>
  
  <ol>
  <li><p>Using the .htaccess based solution works as well, it even looks like as if thats the only change needed (I removed the list() code as I did never get into it and it worked as well).</p>
  
  <p>2.1. Same problem as above, no real logout possible.</p></li>
  </ol>
  
  <p><strong>Update 6</strong></p>
  
  <p>Probably the last or one of my last updates. :-)
  Right now I'm trying to do a "fake logout" by logging the user in as a guest user I created who has only access to <code>/users/login</code> and <code>/pages/home</code>: <code>http://guest:guest@my.domain/users/login</code></p>
  
  <p>Accessing <code>/users/logout</code> might work too, as I'm using this piece of code there:</p>
  
  <pre><code>public function logout() {
      $user = $this-&gt;User-&gt;find('first', array('conditions' =&gt; array('username' =&gt; 'guest')));
      $this-&gt;Auth-&gt;login($user['User']['id']);
  }
  </code></pre>
  
  <p>I simly don't believe, this will be consistent, since I believe the Session data will be deleted some time and the browser still got the active admin login and authenticates using these - am I right?</p>
  
  <p>After that I can login a different User again using <code>http://admin:admin@my.domain/users/login</code>. Not perfect, but works at least for Firefox.</p>
  
  <p>So basically one last question: Any suggestions on how to force a BasicAuth when accessing <code>/users/login</code>? This way I could easily switch users at any time using any client.</p>
  
  <p><strong>Update 7</strong></p>
  
  <p>I found a way to do exactly this with the idea in my accepted answer. I hope I caught all edge cases in this, feel free to correct me if not!</p>
  
  <p>(P.s.: when using ACL and or basic authentication the isAuthorized() in at least the AppController seems to be ignored (it was recognized, but had no effect - when i deleted the method without changing $components, i got an error) which lead to me implementing this without using isAuthorized().)</p>
  
  <p>AppController.php</p>
  
  <pre><code>public function beforeFilter($redirectlogin = true) {
      //Configure AuthComponent
      $this-&gt;Auth-&gt;allow('display', '/users/login');
      $this-&gt;Auth-&gt;loginAction = array('controller' =&gt; 'users', 'action' =&gt; 'login');
      $this-&gt;Auth-&gt;logoutRedirect = array('controller' =&gt; 'pages', 'action' =&gt; 'home');
      $this-&gt;Auth-&gt;loginRedirect = array('controller' =&gt; 'pages', 'action' =&gt; 'home');
      $this-&gt;Auth-&gt;unauthorizedRedirect = array('controller' =&gt; 'HTTPCODE', 'action' =&gt; 'c403');
  
      if($redirectlogin &amp;&amp; $this-&gt;Session-&gt;read('Auth.needs_reauthenticate')) {
          if(!($this-&gt;request-&gt;params['controller'] == $this-&gt;Auth-&gt;loginRedirect['controller'] &amp;&amp; $this-&gt;request-&gt;params['pass'][0] == $this-&gt;Auth-&gt;loginRedirect['action'])) {
              $this-&gt;redirect('/users/login');
          }
      }
   }
  </code></pre>
  
  <p>UsersController.php</p>
  
  <pre><code>public function beforeFilter() {
      parent::beforeFilter(false);
  }
  
      public function login() {
          $this-&gt;autoRender = false;
          $this-&gt;Session-&gt;write('Auth.needs_reauthenticate', true);
          if(!$this-&gt;Session-&gt;check('Auth.count')) {
              $count = 1;
          } else {
              $count = $this-&gt;Session-&gt;read('Auth.count') + 1;
          }
          $this-&gt;Session-&gt;write('Auth.count', $count);
  
          if($this-&gt;Session-&gt;read('Auth.needs_reauthenticate')) {
              if((isset($_SERVER['HTTP_AUTHORIZATION']) &amp;&amp; $this-&gt;Session-&gt;read('Auth.count') == 1) || (!isset($_SERVER['HTTP_AUTHORIZATION']) || empty($_SERVER['HTTP_AUTHORIZATION']) || !$this-&gt;Session-&gt;check('Auth.sent_header_step') || $this-&gt;Session-&gt;read('Auth.sent_header_step') &lt; 1)) {
                  unset($_SERVER['HTTP_AUTHORIZATION']);
                  $this-&gt;Session-&gt;write('Auth.redirectTo', $this-&gt;Auth-&gt;redirect());
  
                  $this-&gt;response-&gt;header(sprintf('WWW-Authenticate: Basic realm="%s"', env('SERVER_NAME')));
                  $this-&gt;response-&gt;statusCode(401);
                  $this-&gt;response-&gt;send();
  
                  $this-&gt;Session-&gt;write('Auth.sent_header_step', 1);
              }       
  
              if(isset($_SERVER['HTTP_AUTHORIZATION'])) {
                  $this-&gt;Session-&gt;write('Auth.sent_header_step', 0);
                  $base64string = base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6));
                  if(!(strlen($base64string) &gt; 1 &amp;&amp; substr($base64string, -1, 1) != ":")) {
                      $_SERVER['PHP_AUTH_USER'] = "";
                      $_SERVER['PHP_AUTH_PW'] = "";
                  }
  
                  $data = true;
              }
  
              $this-&gt;Auth-&gt;logout();
  
              if(isset($data) &amp;&amp; $this-&gt;Session-&gt;read('Auth.count') &gt; 1) {
                  if($this-&gt;Auth-&gt;login()) {
                      $this-&gt;Session-&gt;write('Auth.needs_reauthenticate', false);
                      if($this-&gt;Session-&gt;check('Auth.redirectTo')) {
                          $redirectTo = $this-&gt;Session-&gt;read('Auth.redirectTo');
                          $this-&gt;Session-&gt;delete('Auth.redirectTo');
                          $this-&gt;Session-&gt;delete('Auth.count');
  
                          return $this-&gt;redirect($redirectTo);
                      } else {
                          return $this-&gt;redirect($this-&gt;Auth-&gt;redirect());
                      }
                  } else {
                      $this-&gt;response-&gt;statusCode(403);
                      // my 403 message
                  }
              } else {
  
                  if(!isset($_SERVER['HTTP_AUTHORIZATION']) &amp;&amp; $this-&gt;Session-&gt;read('Auth.count') &gt; 1 &amp;&amp; isset($_SERVER['PHP_AUTH_USER']) &amp;&amp; isset($_SERVER['PHP_AUTH_PW']) &amp;&amp; trim($_SERVER['PHP_AUTH_USER']) != "" &amp;&amp; trim($_SERVER['PHP_AUTH_PW']) != "") {
                      if($this-&gt;Auth-&gt;login()) {
                          $this-&gt;Session-&gt;write('Auth.needs_reauthenticate', false);
                          if($this-&gt;Session-&gt;check('Auth.redirectTo')) {
                              $redirectTo = $this-&gt;Session-&gt;read('Auth.redirectTo');
                              $this-&gt;Session-&gt;delete('Auth.redirectTo');
                              $this-&gt;Session-&gt;delete('Auth.count');
  
                              unset($_SERVER['HTTP_AUTHORIZATION']);
                              unset($_SERVER['PHP_AUTH_USER']);
                              unset($_SERVER['PHP_AUTH_PW']);
                              return $this-&gt;redirect($redirectTo);
                          } else {
                              return $this-&gt;redirect($this-&gt;Auth-&gt;redirect());
                          }
                      } else {
                          $this-&gt;response-&gt;statusCode(403);
                          // my 403 message
                      }
                  }
  
                  $this-&gt;response-&gt;statusCode(403);
                  // my 403 message
              }
          }
      }
  </code></pre>
  
  <p>Thanks in advance</p>
  
  <p>Adrian</p>