在我的网站上,除了一些特定页面(登录,注册,pwd重置)之外,用户需要登录。我已经实现了remember me
功能,效果很好。
我想要实现的是,对于管理页面,用户应该admin role and not remembered
。为了检查此要求,我在相关的access_control规则中使用了allow_if
,但是它拒绝了我的管理员用户的访问权限,虽然会话没有被记住,我可以在调试工具栏上确认该会话有UsernamePasswordToken
。
我的access_control规则如下:(第4个不能工作)
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, allow_if: "has_role('ROLE_ADMIN') and has_role('IS_AUTHENTICATED_FULLY')" }
- { path: ^/, role: IS_AUTHENTICATED_REMEMBERED }
如果我从相关的访问控制规则中删除and has_role('IS_AUTHENTICATED_FULLY')
部分,用户可以通过授权,因此问题似乎就是这部分。
has_role('IS_AUTHENTICATED_FULLY')
有什么问题?
Symfony版本:2.7.5
答案 0 :(得分:1)
好吧,我找到了解决问题的解决方法。
官方网站上的 How to use Expressions in Security, Routing, Services, and Validation食谱文章有相关部分,并说明可能使用is_remember_me()
和is_fully_authenticated()
方法检查存在IS_AUTHENTICATED_REMEMBERED
和IS_AUTHENTICATED_FULLY
角色各自。
is_remember_me与检查IS_AUTHENTICATED_REMEMBERED不同
is_remember_me和is_authenticated_fully函数与使用isGranted函数的IS_AUTHENTICATED_REMEMBERED和IS_AUTHENTICATED_FULLY类似 - 但它们不相同。以下显示了不同之处:
use Symfony\Component\ExpressionLanguage\Expression;
// ...
$ac = $this->get('security.authorization_checker');
$access1 = $ac->isGranted('IS_AUTHENTICATED_REMEMBERED');
$access2 = $ac->isGranted(new Expression(
'is_remember_me() or is_fully_authenticated()'
));
这里,$ access1和$ access2将是相同的值。与IS_AUTHENTICATED_REMEMBERED和IS_AUTHENTICATED_FULLY的行为不同,如果用户通过remember-me cookie进行身份验证,则is_remember_me函数仅返回true,如果用户在此会话期间实际登录(即完全成熟),则is_fully_authenticated仅返回true。
使用该文档部分,我按如下方式修改了访问控制规则,现在可以使用了:
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, allow_if: "has_role('ROLE_ADMIN') and is_fully_authenticated()" }
- { path: ^/, role: IS_AUTHENTICATED_REMEMBERED }
但是,我仍然认为这是一个问题,并不是预期的行为。所以,我在官方问题跟踪器中打开了一个问题:
Github问题: #16096 - Expression engine has_role() function can't process implicit roles
答案 1 :(得分:0)
添加代码以拒绝访问有两种方法可以拒绝访问 东西:
security.yml中的
- access_control允许您保护URL模式(例如/ admin / *)。这很容易,但不太灵活;
通过security.authorization_checker服务在您的代码中- 。
醇>
你试图使用第一种方式,但只能用第二种方式。
您需要在控制器中执行授权检查,并在其中加入代码
if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
throw $this->createAccessDeniedException();
}
您也可以使用SensioFrameworkExtraBundle并只为控制器添加注释
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
...
/**
* @Security("is_granted('IS_AUTHENTICATED_FULLY')")
*/
public function showAction()
{
}