为什么覆盖密码散列会导致 url 在 magento 管理中中断?
Why has overriding password hashing caused urls to break in magento admin?
我在自定义模块中覆盖了 Mage_Core_Model_Encryption
的 hash($data)
和 validateHash($password, $hash)
。它有效,我可以使用我的密码登录到管理区域,并使用新的哈希值正确验证;但是,我无法在管理区域中导航。我看到类似密码的散列成为 url 的一部分:
admin/dashboard/index/key/[bcrypt hash here]
。浏览器无法重定向到生成的 url。谁能建议我在不破坏 url 的情况下覆盖密码哈希?提前致谢。
如果有帮助,我的配置 xml 如下所示:
<?xml version="1.0" ?>
<config>
<modules>
<Mycompany_Encryption>
<version>0.1</version>
<depends>Mage_Core</depends>
</Mycompany_Encryption>
</modules>
<global>
<models>
<core>
<rewrite>
<encryption>Mycompany_Encryption_Model_Encryption</encryption>
</rewrite>
</core>
</models>
<helpers>
<core>
<encryption_model>Mycompany_Encryption_Model_Encryption</encryption_model>
</core>
</helpers>
</global>
</config>
更新::(根据下面的两条评论)如何使用 password_hash 而不是 md5 进行密码验证,同时允许 url 密钥使用url 友好的哈希函数?
我对核心文件做了一些研究,看起来通过工厂可以实现你想要实现的目标。
遗憾的是,看起来 Magento 完成了部分工作,但不是全部。
Mage_Core_Model_Encryption::_getCrypt($key = null)
protected function _getCrypt($key = null)
{
if (!$this->_crypt) {
if (null === $key) {
$key = (string)Mage::getConfig()->getNode('global/crypt/key');
}
$this->_crypt = Varien_Crypt::factory()->init($key);
}
return $this->_crypt;
}
Varien_Crypt 这让我说这还没有完全完成,那是一个工厂,但在上面的函数中调用时没有参数,所以,是的,没办法改变工厂返回的对象,唉。
class Varien_Crypt
{
static public function factory($method='mcrypt')
{
$uc = str_replace(' ','_',ucwords(str_replace('_',' ',$method)));
$className = 'Varien_Crypt_'.$uc;
return new $className;
}
}
但是知道这两个是这样设计的,您可以:重写 Varien_Crypt
以实例化另一个 class 并基于 class Varien_Crypt_Mcrypt
的方法,实施相同的方法并获得您想要实现的目标。
通过查看这个,我还发现有人在 magento Q&A of stack exchange his module to have a more secure password encryption 上发帖。
它在 GitHub 上采用 BSD 许可,因此 here is his post on the network
和 here is the module, called pbkdf2, repository
也许您可以从他的实现方式中找到一些有用的东西(我没有花时间看他的代码,太难了)。
Mage_Core_Model_Encryption
的 encrypt/decrypt 函数未在 url 中使用。
基本上,有两种方法可以解决冲突。一种是基于在客户身份验证方法上使用事件观察器来实现新的哈希。另一种方法,对我来说效果更好的方法是扩展 Mage_Adminhtml_Model_Url
并覆盖 getSecretKey
方法。
[评论中链接的两个回购协议对我们的学习很有帮助。]
为了解决这个问题,我在 models
:
的 config.xml 中添加了一个节点
<adminhtml>
<rewrite>
<url>Mycompany_Encryption_Model_Adminhtml_Url</url>
</rewrite>
</adminhtml>
然后添加文件Mycompany/Encryption/Model/Adminhtml/Url.php
:
class Mycompany_Encryption_Model_Adminhtml_Url extends Mage_Adminhtml_Model_Url
{
public function getSecretKey($controller = null, $action = null)
{
$salt = Mage::getSingleton('core/session')->getFormKey();
$p = explode('/', trim($this->getRequest()->getOriginalPathInfo(), '/'));
if (!$controller) {
$controller = !empty($p[1]) ? $p[1] : $this->getRequest()->getControllerName();
}
if (!$action) {
$action = !empty($p[2]) ? $p[2] : $this->getRequest()->getActionName();
}
$secret = $controller . $action . $salt;
// Overriding getHash() to use a diff hash than passwords.
return Mage::helper('core')->getEncryptor()->urlHash($secret);
}
}
最后,我通过添加 urlHash 方法更新了我的 Mycompany/Encryption/Model/Encryption.php
(除了已经位于那里的 hash
、validateHash
和 getHash
函数):
public function urlHash($value)
{
return md5($value);
}
我本可以在 getSecretKey
的末尾返回 md5($secret)
,这也有效,但此方法演示了更多有助于实际操作的 Mage 方法。
我还没有完全测试我的模块,但这似乎与调用 getSecretKey 的每个地方都完全兼容。
我在自定义模块中覆盖了 Mage_Core_Model_Encryption
的 hash($data)
和 validateHash($password, $hash)
。它有效,我可以使用我的密码登录到管理区域,并使用新的哈希值正确验证;但是,我无法在管理区域中导航。我看到类似密码的散列成为 url 的一部分:
admin/dashboard/index/key/[bcrypt hash here]
。浏览器无法重定向到生成的 url。谁能建议我在不破坏 url 的情况下覆盖密码哈希?提前致谢。
如果有帮助,我的配置 xml 如下所示:
<?xml version="1.0" ?>
<config>
<modules>
<Mycompany_Encryption>
<version>0.1</version>
<depends>Mage_Core</depends>
</Mycompany_Encryption>
</modules>
<global>
<models>
<core>
<rewrite>
<encryption>Mycompany_Encryption_Model_Encryption</encryption>
</rewrite>
</core>
</models>
<helpers>
<core>
<encryption_model>Mycompany_Encryption_Model_Encryption</encryption_model>
</core>
</helpers>
</global>
</config>
更新::(根据下面的两条评论)如何使用 password_hash 而不是 md5 进行密码验证,同时允许 url 密钥使用url 友好的哈希函数?
我对核心文件做了一些研究,看起来通过工厂可以实现你想要实现的目标。
遗憾的是,看起来 Magento 完成了部分工作,但不是全部。
Mage_Core_Model_Encryption::_getCrypt($key = null)
protected function _getCrypt($key = null)
{
if (!$this->_crypt) {
if (null === $key) {
$key = (string)Mage::getConfig()->getNode('global/crypt/key');
}
$this->_crypt = Varien_Crypt::factory()->init($key);
}
return $this->_crypt;
}
Varien_Crypt 这让我说这还没有完全完成,那是一个工厂,但在上面的函数中调用时没有参数,所以,是的,没办法改变工厂返回的对象,唉。
class Varien_Crypt
{
static public function factory($method='mcrypt')
{
$uc = str_replace(' ','_',ucwords(str_replace('_',' ',$method)));
$className = 'Varien_Crypt_'.$uc;
return new $className;
}
}
但是知道这两个是这样设计的,您可以:重写 Varien_Crypt
以实例化另一个 class 并基于 class Varien_Crypt_Mcrypt
的方法,实施相同的方法并获得您想要实现的目标。
通过查看这个,我还发现有人在 magento Q&A of stack exchange his module to have a more secure password encryption 上发帖。
它在 GitHub 上采用 BSD 许可,因此 here is his post on the network
和 here is the module, called pbkdf2, repository
也许您可以从他的实现方式中找到一些有用的东西(我没有花时间看他的代码,太难了)。
Mage_Core_Model_Encryption
的 encrypt/decrypt 函数未在 url 中使用。
基本上,有两种方法可以解决冲突。一种是基于在客户身份验证方法上使用事件观察器来实现新的哈希。另一种方法,对我来说效果更好的方法是扩展 Mage_Adminhtml_Model_Url
并覆盖 getSecretKey
方法。
[评论中链接的两个回购协议对我们的学习很有帮助。]
为了解决这个问题,我在 models
:
<adminhtml>
<rewrite>
<url>Mycompany_Encryption_Model_Adminhtml_Url</url>
</rewrite>
</adminhtml>
然后添加文件Mycompany/Encryption/Model/Adminhtml/Url.php
:
class Mycompany_Encryption_Model_Adminhtml_Url extends Mage_Adminhtml_Model_Url
{
public function getSecretKey($controller = null, $action = null)
{
$salt = Mage::getSingleton('core/session')->getFormKey();
$p = explode('/', trim($this->getRequest()->getOriginalPathInfo(), '/'));
if (!$controller) {
$controller = !empty($p[1]) ? $p[1] : $this->getRequest()->getControllerName();
}
if (!$action) {
$action = !empty($p[2]) ? $p[2] : $this->getRequest()->getActionName();
}
$secret = $controller . $action . $salt;
// Overriding getHash() to use a diff hash than passwords.
return Mage::helper('core')->getEncryptor()->urlHash($secret);
}
}
最后,我通过添加 urlHash 方法更新了我的 Mycompany/Encryption/Model/Encryption.php
(除了已经位于那里的 hash
、validateHash
和 getHash
函数):
public function urlHash($value)
{
return md5($value);
}
我本可以在 getSecretKey
的末尾返回 md5($secret)
,这也有效,但此方法演示了更多有助于实际操作的 Mage 方法。
我还没有完全测试我的模块,但这似乎与调用 getSecretKey 的每个地方都完全兼容。