CakePHP 2:覆盖AuthComponent的“密码”方法

时间:2012-07-16 17:44:09

标签: cakephp authentication passwords

我的目标是为每个用户提供一个独特的盐,而不是仅为每个用户使用Configure::read('Security.salt')

我知道CakePHP 2.x不再自动散列密码。这允许我对密码执行模型验证,这是非常好的。但是,我没有看到我可以覆盖AuthComponent的“密码”方法的方法。因此,即使我可以控制密码在保存到数据库之前如何进行哈希处理,但我无法控制在执行实际登录时如何对密码进行哈希处理。来自食谱:

  

在调用之前,您不需要哈希密码   $this->Auth->login()

如何使$this->Auth->login()使用自定义密码哈希方法?

感谢。

更新:我最终选择了Hannibal Lecter博士的答案(创建自定义身份验证对象)。这是如何做到的:

旧代码:

$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email')));

新代码(将“表格”更改为“自定义”):

$this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email')));

创建“app / Controller / Component / Auth / CustomAuthenticate.php”并使其如下所示:

<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');

class CustomAuthenticate extends FormAuthenticate {
}

从“lib / Cake / Controller / Component / Auth / BaseAuthenticate.php”复制“_findUser”和“_password”方法,并将它们粘贴到“CustomAuthenticate”类中。然后对“_findUser”方法进行以下两个修改:

  1. 从“$ conditions”数组中删除此行:$model . '.' . $fields['password'] => $this->_password($password),

  2. if (empty($result) || empty($result[$model])) {更改为if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this->_password($password, $result[$model]['id'])) {

  3. 然后对“_password”方法进行以下两个修改:

    1. 通过将protected function _password($password) {更改为protected function _password($password, $id) {

    2. 来创建“$ id”参数
    3. return Security::hash($password, null, true);更改为return Security::hash($password, null, Configure::read('Security.salt') . $id);

    4. 更新盐值

      最后,使用与上述逻辑相同的逻辑更新所有AuthComponent::password次使用Security::hash

4 个答案:

答案 0 :(得分:4)

你可以创建一个custom auth object并随意哈希密码。看看existing auth objects,了解它们的工作原理。

答案 1 :(得分:1)

您是否考虑过不使用Auth-&gt; login()调用,而是使用模型中当前实现的代码? (http://api20.cakephp.org/view_source/auth-component#line-506)您可以根据自己的需要重写此内容。

答案 2 :(得分:1)

如果想要了解更多关于为每个密码加盐的原因是否是散列密码的正确方法(有代码示例),请访问:http://crackstation.net/hashing-security.htm

这里发布的代码可能略有改进,就是接受我刚刚链接到的文章的建议,并生成“新的随机盐”......“每次用户创建帐户或更改密码时。 “

此处发布的实现使用原始Auth的硬编码静态盐加上用户ID作为salt的组合,这意味着每当用户更改密码时,相同的盐将被重复使用。因此,如果您想遵循此散列指南的建议,则每次用户创建/更改其密码时都需要生成新的随机盐,并且必须将该唯一salt与散列密码一起存储在users表中。

你可以使用他们的随机盐生成器:

define("PBKDF2_SALT_BYTES", 24);
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));

按照惯例,将其存储在名为“salt”的新字段的users表中。由于代码已经为您提供了用户ID,因此您可以随时根据需要存储/查找salt。

本文中还提到了一个关于“慢哈希函数”的部分,它使用了一种称为“密钥拉伸”的技术,以及如何使用标准算法如PBKDF2或bcrypt来实现。提供了PHP代码示例,可以将其复制并粘贴到您的自定义Auth实现中,以增强安全性。

CakePHP开发者Mark Story发布了一篇关于如何implement bcrypt in CakePHP's Auth

的博客文章

在评论部分,Mark Story评论说CakePHP 2.3将有一些新的内置功能来生成bcrypt哈希。

答案 3 :(得分:0)

蛋糕中的Atleast 2.3已经使用了一种独特的盐,即使配置值中的盐总是相同的。我不确定旧版本是否也适用。

您也可以使用Configure :: write(“Security.salt”,$ superAwesomeUserSpecificSalt)更改User模型中beforeSave()函数中的salt;