我在我的项目中使用安全组件,有没有办法在开发时获得有关错误的详细描述?例如: - 如果在视图中添加任何字段而不使用cakephp的form方法,则在blackHoleCallback函数中返回错误为'auth'。相反,我需要因为它返回错误的原因。因为它需要花费很多时间来纠正这个问题。有没有办法得到详细的错误描述?
答案 0 :(得分:6)
您所要做的就是找对方
app/tmp/logs/error.log
文件如果您查看错误日志,您会看到如下条目:
2013-03-16 17:24:29 Error: [BadRequestException] The request has been black-holed
#0 root/lib/Cake/Controller/Component/SecurityComponent.php(228): SecurityComponent->blackHole(Object(FacebookUsersController), 'csrf')
#1 [internal function]: SecurityComponent->startup(Object(FacebookUsersController))
#2 root/lib/Cake/Utility/ObjectCollection.php(130): call_user_func_array(Array, Array)
#3 [internal function]: ObjectCollection->trigger(Object(CakeEvent))
#4 root/lib/Cake/Event/CakeEventManager.php(246): call_user_func(Array, Object(CakeEvent))
#5 root/lib/Cake/Controller/Controller.php(670): CakeEventManager->dispatch(Object(CakeEvent))
#6 root/lib/Cake/Routing/Dispatcher.php(183): Controller->startupProcess()
#7 root/lib/Cake/Routing/Dispatcher.php(161): Dispatcher->_invoke(Object(FacebookUsersController), Object(CakeRequest), Object(CakeResponse))
#8 root/app/webroot/index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
#9 {main}
如果您处于调试模式,则错误发生时屏幕上也会显示此错误。 e.g:
The request has been black-holed
Error: The requested address '/admin/fooby/edit/1' was not found on this server.
Stack Trace
CORE/Cake/Controller/Component/SecurityComponent.php line 228 → SecurityComponent->blackHole(FacebookUsersController, string)
[internal function] → SecurityComponent->startup(FacebookUsersController)
CORE/Cake/Utility/ObjectCollection.php line 130 → call_user_func_array(array, array)
[internal function] → ObjectCollection->trigger(CakeEvent)
CORE/Cake/Event/CakeEventManager.php line 246 → call_user_func(array, CakeEvent)
CORE/Cake/Controller/Controller.php line 670 → CakeEventManager->dispatch(CakeEvent)
CORE/Cake/Routing/Dispatcher.php line 183 → Controller->startupProcess()
CORE/Cake/Routing/Dispatcher.php line 161 → Dispatcher->_invoke(FacebookUsersController, CakeRequest, CakeResponse)
APP/webroot/index.php line 96 → Dispatcher->dispatch(CakeRequest, CakeResponse)
使用特定错误的详细信息(即您发布的数据以及当时会话中的确切令牌数据),可以回答什么问题把你带到了这里,没有这个:
抛出错误的行在上面的堆栈跟踪中,错误来自CORE/Cake/Controller/Component/SecurityComponent.php line 228
- 打开文件并查看代码是什么:
if ($isPost && $isNotRequestAction && $this->csrfCheck) {
if ($this->_validateCsrf($controller) === false) {
return $this->blackHole($controller, 'csrf');
}
}
从中可以明显看出,函数_validateCsrf
负责对请求进行黑洞处理。这不应该是一个惊喜。
在该函数的源代码中查看:
protected function _validateCsrf(Controller $controller) {
$token = $this->Session->read('_Token');
$requestToken = $controller->request->data('_Token.key');
if (isset($token['csrfTokens'][$requestToken]) && $token['csrfTokens'][$requestToken] >= time()) {
if ($this->csrfUseOnce) {
$this->Session->delete('_Token.csrfTokens.' . $requestToken);
}
return true;
}
return false;
}
根据该函数返回false的原因,确定继续调试的方式。
调试CSRF错误的必然结果是您需要修改configuration of the Security component。
例如,您是否想要重复使用令牌,因为您的应用在页面加载之间多次提交相同的表单?
您是否通过向表单数据添加新字段来自动使表单请求失效 - 您可以使用the unlockedFields property从csrf检查中排除这些字段。
你也可以简单地disable CSRF checks完成。这有明显的安全后果 - 但如果您正在努力使用该组件,那么这是一种简单的解决方法,也是您目前遇到的问题。
答案 1 :(得分:3)
为了查看我在代码中挖掘的机制,看看如何创建FormHelper哈希以及SecurityComponent验证如何检查哈希。以下是如何准确了解幕后发生的事情。
检查FormHelper的输入。打开CORE / Cake / View / Helper / FormHelper.php。在secure()函数中,在$ files = Security :: hash行周围添加一些pr行,看看如何构建标记:
pr($fields);//hashed into computed token on next line
$fields = Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt'), 'sha1');
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($fields); //computed token passed via hidden token field in form
检查表单的处理方式 现在检查提交的表单如何处理并与传递的令牌进行比较: 打开CORE / Cake / Controller / Component / SecurityComponent.php。在_validatePost()例程的末尾插入一些pr行:
pr($fieldList); //hashed into computed token
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($token); //passed token from FormHelper
pr($check); //computed token
希望这可以帮助那些遇到锁定/解锁或丢失字段问题的人快速弄清楚蛋糕内部的情况。
答案 2 :(得分:1)
还要记住,Token
生成的FormHelper
与使用Session检索到的bu蛋糕之间必须完全匹配。正如文档所说,当您动态生成输入或进行ajax调用时,可能会发生不匹配:请记住序列化表单并通过ajax提交!
如果您使用FormHelper
生成的输入标记未生成,则必须解锁。例如,在beforeFilter()
:
$this->Security->unlockedFields =
array('MyModel.some_field1','MyModel.some_field2')
其中field1
和field2
是“手动”生成的字段,即不使用帮助程序。
答案 3 :(得分:1)
回答这个问题:“有没有办法获得详细的错误描述?”
首先,当涉及到SecurityComponent时,为控制器添加更多有价值的调试。这是一种方法:
public function beforeFilter() {
parent::beforeFilter();
//your beforeFilter code
//Enable CSRF and other protections
$this->Security->csrfExpires = '+1 hour';
$this->Security->csrfUseOnce = true;
$this->Security->blackHoleCallback = 'blackhole';
}
public function blackhole($errorType) {
$errorMap['auth'] = 'form validation error, or a controller/action mismatch error.';
$errorMap['csrf'] = 'CSRF error.';
$errorMap['get'] = 'HTTP method restriction failure.';
$errorMap['post'] = $errorMap['get'];
$errorMap['put'] = $errorMap['get'];
$errorMap['delete'] = $errorMap['get'];
$errorMap['secure'] = 'SSL method restriction failure.';
$errorMap['myMoreValuableErrorType'] = 'My custom and very ' .
'specific reason for the error type.';
CakeLog::notice("Request to the '{$this->request->params['action']}' " .
"endpoint was blackholed by SecurityComponent due to a {$errorMap[$errorType]}");
}
正如AD7six所提到的,请看一下CORE/Cake/Controller/Component/SecurityComponent.php
。具体来说是SecurityComponent::startup()
。在该方法中,您会注意到SecurityComponent::blackhole()
方法运行了几次。只要条件未通过安全检查,它就会运行,如下所示:
return $this->blackHole($controller, 'auth');
在这种情况下,“auth”表示失败的安全检查类型。您可以自定义'auth'字符串以获得更多价值。例如,使用'myMoreValuableErrorType'代替'auth',然后将其映射到更有意义的东西。
因此,在安全检查失败时,不是运行$this->blackHole($controller, 'auth')
,而是运行$this->blackHole($controller, 'myMoreValuableErrorType')
,然后使用上面的代码将'myMoreValuableErrorType'映射到有关失败原因的特定原因。