2012-07-16 49 views
10

我的目標是爲每個用戶提供一個獨特的salt,而不是僅爲每個用戶使用Configure::read('Security.salt')CakePHP 2:覆蓋AuthComponent的「密碼」方法

我知道CakePHP 2.x不再自動哈希密碼。這使我可以對密碼進行模型驗證,這非常好。但是,我沒有看到可以重寫AuthComponent的「密碼」方法的方法。因此,即使我可以控制密碼在保存到數據庫之前如何散列,我無法控制在執行實際登錄時密碼是如何散列的。從食譜:

你不需要調用 $this->Auth->login()之前哈希密碼。

我該怎麼做才能使$this->Auth->login()使用密碼散列的自定義方法?

謝謝。

更新:我結束了與漢尼拔萊克博士的答案(創建一個自定義的身份驗證對象)。以下是如何做到這一點:

舊代碼:

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

新的代碼(變 「形」 到 「自定義」):

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

創建「應用程序/控制器/組件/認證/ CustomAuthenticate.php 「使它看起來像這樣:

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

class CustomAuthenticate extends FormAuthenticate { 
} 

複製 」_findUser「 和 」_password的lib /蛋糕/控制/通訊「 的方法」 ponent/Auth/BaseAuthenticate.php「並將它們粘貼到」CustomAuthenticate「類中。然後進行以下兩處修改 「_findUser」 的方法:

  1. 從 「$條件」 陣列刪除此行:$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'])) {

然後使對「_password」方法進行以下兩種修改:

  1. 通過改變通過改變protected function _password($password) {protected function _password($password, $id) {

  2. 更新salt值創建「$ ID」參數return Security::hash($password, null, true);return Security::hash($password, null, Configure::read('Security.salt') . $id);

最後,更新的AuthComponent::password所有出現使用Security::hash具有相同的邏輯以上。

回答

4

你可以創建一個custom auth object然後按你喜歡的方式散列密碼。看看existing auth objects以瞭解它們的工作原理。

+0

這工作!我用相關的代碼更新了我的問題。謝謝! – Nick 2012-07-17 00:11:28

1

您是否考慮過不使用Auth-> login()調用,而是使用模型中當前實現的代碼? (http://api20.cakephp.org/view_source/auth-component#line-506)你可以重寫這個以適應你的需求。

+0

我不知道我會如何去做這件事,它似乎不是一個非常開發人員友好的方式來做到這一點。爲每個用戶提供獨特的鹽絕對不是一個不尋常的目標。你有一些示例代碼?無論哪種方式,我感謝您的時間 – Nick 2012-07-16 19:38:24

1

對於任何想要了解更多關於爲什麼醃製每個密碼是散列密碼的正確方法(w /代碼示例)的更多信息,請訪問: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)); 

按照慣例,將其存儲在用戶表中一個名爲「鹽」的新領域。由於代碼已經爲您提供了用戶標識,因此您可以隨時根據需要存儲/查找鹽。

本文還提到使用稱爲「密鑰擴展」的技術以及如何使用標準算法(如PBKDF2或bcrypt)實現的「慢哈希函數」部分。提供的PHP代碼示例可以複製並粘貼到您的自定義Auth實現中,以提高安全性。

CakePHP的開發人員馬克的故事張貼到implement bcrypt in CakePHP's Auth

在評論部分如何,馬克的故事評論說,CakePHP的2.3將有一些新的內置功能來生成散列bcrypt博客條目。

0

至少在蛋糕2.3中已經使用了一種獨特的鹽,即使配置值中的鹽總是相同的。我不確定這是否適用於舊版本。您可以通過使用Configure :: write(「Security.salt」,$ superAwesomeUserSpecificSalt)更改用戶模型中的beforeSave()函數中的鹽值。