我正在尝试测试Symfony2完成的CRSF保护系统,非常感谢他们 我的security.yml模板:(我修改了默认模板。)
security:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/demo/secured/login$
security: false
secured_area:
pattern: ^/demo/secured/
form_login:
check_path: _security_check
login_path: _demo_login
csrf_provider: form.csrf_provider
logout:
path: _demo_logout
target: _demo
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
access_control:
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
以我的形式:
<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">
产生类似这样的东西:
<input type="hidden" name="_csrf_token" value="cKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw">
我不知道symfony如何使用令牌处理验证,但在提交登录之前,我使用firebug手动更改了令牌的值,如下所示:
<input type="hidden" name="_csrf_token" value="MODIFIEDcKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw">
当我提交登录信息时,我会登录。这意味着令牌没有影响力。 我哪里错了?
狙击狩猎
表格Html!
<form id="Loginform" onsubmit="OrganicLogin();return false;">
<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">
<div id="Loginresponse" style="display:none;"></div>
<div class="form-group" style="overflow:hidden;">
<label style="margin-top:10px;" for="inputUsername" class="col-lg-2 control-label">Username</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="inputUsername" placeholder="Username" style="width:215px;float:right;">
</div>
</div>
<div class="form-group" style="overflow:hidden;" >
<label style="margin-top:10px;" for="inputPassword" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<input type="password" class="form-control" id="inputPassword" placeholder="Password" style="width:215px;float:right;">
</div>
</div>
<div class="form-group" style="overflow:hidden;text-align:center;" >
<button type="submit" class="btn btn-primary btn-block" id="submitButton">Access</button>
</div></form>
是的!我做了
实际上我一直在争论的是,我以原生的方式进行登录,使用JS读取数据,向控制器发送POST请求,控制器检查输入并设置会话。
不,全部手工完成
实际上这是我第一次使用security.yml,我刚刚删除了一些我认为对此线程无用的部分
no ..
答案 0 :(得分:2)
我猜测你的更改后的令牌没有被发布。坚持下去:
namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider;
class DefaultCsrfProvider implements CsrfProviderInterface
{
public function isCsrfTokenValid($intention, $token)
{
die('csrf token ' . $intention . ' ' . $token);
return $token === $this->generateCsrfToken($intention);
}
如果到达骰子,那么你知道你的配置是可以的,当然你可以看到实际发布的令牌。
不用说,你也应该清除。
=============================================== ======
更新1 - 经过多次评论后,我们确定没有调用die()。进展。
不幸的是,我们仍然需要确切地验证海报如何配置他们的系统。
下一步 - 登录而不通过firebug调整csrf令牌并验证是否已达到die语句。
以这种或那种方式报告。
毋庸置疑(但无论如何我都会说),请确保在尝试重新登录前退出。
=============================================== =========
更新2 - 即使正常登录也无法达到die语句。
所以现在是我最喜欢的部分。狙击狩猎。基本上,我在阅读问题时做了一些假设。需要通过询问一些基本问题来确定哪些假设是不正确的。
您使用的是哪个版本的Symfony 2。我假设至少是S2.1。
你怎么知道系统已经签了你?您是否正在使用调试工具栏并且它是否显示您正在进行身份验证?当您尝试使用不正确的密码登录时会发生什么?
使用浏览器的查看源功能,将生成的表单复制到您的问题中。特别是我想看到action属性,但我也希望看到输入元素。
您实际上是否将die语句添加到vendor / symfony / symfony / src / Symfony / Component / Form / Csrf / CsrfProvider / DefaultCsrfProvider.php?编辑后是否保存了文件?
您实际上正在使用标准的form_login流程吗?您没有任何代码,例如,检查用户密码?
您是否正在使用其他任何捆绑包,例如FOSUserBundle?
你问题中的security.yml文件真的是你的实际文件吗?复制后你没有“清理它”吗?
您是否已将应用程序检入github?如果是,那么你能提供链接吗?查看整个应用程序可能是解决此问题的最快方法。
现在应该足够了。用你的答案更新你的问题。
=============================================== ==========================
更新3 - 情节变粗
当我输入上述问题时,我们发现基本登录系统本身没有正确配置。调试工具栏指示用户未经过身份验证。更多进步!正如经常发生的那样,症状掩盖了实际问题。
安全系统可以说是Symfony 2中最复杂的组件,典型的开发人员需要与之交互。配置它时很容易混淆,很难排除故障。一个微小的错字可以使事情融化。对于开发人员来说,了解如何实现安全性也非常重要。除非你是一个像Target或Home Depot这样的大公司。
我的建议是使用composer创建一个新的Symfony 2项目。然后逐步完成http://symfony.com/doc/current/book/security.html并配置安全系统。让它成为理解安全性的参考应用程序。
在流程结束时,我怀疑您已经找到了问题并可以将解决方案应用于您现有的应用程序。作为奖励,您可以参考未来的问题。
=============================================== ===================
更新4 - 令人兴奋的结论
现在我们发现正在使用自定义和天真的登录系统。
我仍然建议重新开始一个新项目并让Symfony 2工作。之后,如果你真的想,你可以调整登录表单以使用javascript。
如果你真的真的想要使用自己的系统,请从这里开始:Manual authenticate user
但是你没有特别理由抛弃Symfony的主要优势之一。
答案 1 :(得分:1)
它应该工作的方式是Symfony生成一个CSRF令牌,它会自动插入到表单中。它将此令牌存储在当前会话中。提交表单时,它会将提交的标记与存储在会话中的值进行比较。关于你的具体情况,它听起来似乎没有实际启用CSRF,它可能与安全上下文没有在启用CSRF的安全区域防火墙和登录防火墙之间共享的安全上下文有关。
尝试在security.yml中删除此位:
login:
pattern: ^/demo/secured/login$
security: false
而是将其移至secured_area上下文并使用访问控制来授予访问权限:
...
form_login:
check_path: _security_check
login_path: login
...
access_control:
- { path: ^/demo/secured/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
或者,您可以尝试为登录防火墙添加context: secured_area
。根据我的经验,在与安全区域相同的上下文中没有登录防火墙会阻止您完全从登录控制器中访问安全上下文。