Bonjour,
essayant de mettre en place un webservice RESTful, je me suis donné la peine d'utiliser une authentification HTTP Basic. Cependant, mon principal problème est l'implémentation de ce type d'authentification.
J'utilise un PasswordHasher custom, et n'utilise l'authentification Basic uniquement pour les requêtes avec une extension de fichier (ici JSON/XML pour l'utilité du webservice), afin d'avoir un site "double-face" (qui serve de content provider et d'application telle quelle).
voici mon code :
Controller/AppController.php
<?php
class AppController extends Controller
{
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'users',
'action' => 'getFields'
),
'authenticate' => array(
'Form' => array(
'passwordHasher' => array('className' => 'Joomla')
)
)
),
'RequestHandler'
);
public function beforeFilter()
{
// Change the authentication if using REST
if($this->params'ext'] == 'json' || $this->params'ext'] == 'xml')
{
$this->Auth->authenticate = array(
'Basic' => array(
'passwordHasher' => array('className' => 'Joomla')
)
);
// Ensure AuthComponent doesn’t try to read user info from session.
AuthComponent::$sessionKey = false;
}
$this->Auth->allow('index', 'view');
}
}
---]
Controller/UsersController.php
class UsersController extends AppController
{
function beforeFilter()
{
parent::beforeFilter();
$this->Auth->allow('add', 'logout');
}
public function login()
{
if($this->request->is('post'))
{
$usernameForm = $this->request->data'User']'username'];
$passwordForm = $this->request->data'User']'password'];
$this->request->data'User']'password'] = $passwordForm . ':' . $this->User->getUserSalt($usernameForm);
if($this->Auth->login())
{
return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash("Login et/ou mot de passe invalides !");
}
}
}
---]
Controller/Components/JoomlaPasswordHasher.php
<?php
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
class JoomlaPasswordHasher extends AbstractPasswordHasher
{
public function hash($password)
{
return $this->_joomlaEncryption($password);
}
public function check($password, $hashedPassword)
{
return ($this->_joomlaEncryption($password) === $hashedPassword);
}
private function _joomlaEncryption($password)
{
$password = explode(':', $password);
$salt = $password[1];
// On hash selon la methode joomla et on compare
$hashed = md5($password[0].$salt) . ':' . $salt;
return $hashed;
}
}
Je tiens à dire qu'en authentification Form, tout fonctionne parfaitement. Je suspecte que mon "assignement" de l'authenticate en mode Basic dans AppController::beforeFilter() ne prends pas en compte le passwordHasher... mais bon ça n'aurait aucun sens, on assigne une valeur à une variable...
Résultat de tout ça, en authentification basic, le "prompt" d'authentification ne fait que demander les credentials. Il ne renvoie vers rien jusqu'a que je clique sur "annuler", pour m'envoyer vers un flux json avec le code http 401 (unauthorized)
En espérant que quelqu'un ait une solution !
Merci encore !
OK. J'ai trouvé l'origine du problème : la config serveur.
Le serveur est un mutualisé de chez OVH configuré en CGI/FastCGI.
J'ai essayé cette manip', mais aucun effet. J'investigue sur le sujet, mais cela vient a 100% du serveur, l'ayant installé sur un dédié (personnel), le login n'est apparu qu'une fois, tout a "bien" fonctionné (j'ai un petit souci avec le passwordHasher mais cela n'a rien à voir).
Si quelqu'un a une solution autre que celle décrite au dessus... :(
Merci