【问题标题】:How to identify if a user is being impersonated in Symfony2?如何识别用户是否在 Symfony2 中被模拟?
【发布时间】:2011-09-16 08:02:19
【问题描述】:

在使用 Symfony2 构建的应用程序中,我们希望超级管理员能够模拟其他用户。这很容易通过给超级管理员用户 ROLE_ALLOWED_TO_SWITCH 角色来完成。切换是通过调用“somewhere?_switch_user=”来实现的,如参考文档中所建议的那样。

然而,问题是在模板中检测当前用户是否实际被模拟,以便在页面上打印指向“somewhere?_switch_user=_exit”的链接,从而使模拟用户能够返回到她的真实用户。

【问题讨论】:

    标签: symfony impersonation


    【解决方案1】:

    我有一段时间没有使用 Symfony2,所以我不确定,但是当你切换到另一个用户时,你会获得分配给该用户的所有角色和一个额外的角色:ROLE_PREVIOUS_ADMIN。所以我想你需要做的就是使用 voter 来检查这个角色是否分配给了使用 voter 的当前用户。

    // Twig
    
    {% if is_granted('ROLE_PREVIOUS_ADMIN') %}
        <a href="...?_switch_user=_exit">EXIT</a>
    {% endif %}
    
    // PHP
    
    <?php if ($view['security']->isGranted('ROLE_PREVIOUS_ADMIN')): ?>
        <a href="...?_switch_user=_exit">EXIT</a>
    <?php endif ?>
    

    【讨论】:

    • 有没有办法得到冒名顶替者的ID?这对于模拟者进行更新并且我们希望审计跟踪能够识别模拟者的原始 ID 的情况很有用。
    • @anushr: 是的,使用?_switch_user=_exit(至少从2.3 开始就存在)。
    【解决方案2】:

    如何获取有关模仿者的更多详细信息的示例:

    use Symfony\Component\Security\Core\Role\SwitchUserRole;
    
    
    $sec = $this->get('security.context');
    
    if($sec->isGranted('ROLE_PREVIOUS_ADMIN')) {
      foreach($sec->getToken()->getRoles() as $role) {
        if ($role instanceof SwitchUserRole) {
          $admin_user = $role->getSource()->getUser();
        }
      }
    }
    

    然后您将 admin_user 作为原始用户对象。请记住使用 SwitchUserRole。

    【讨论】:

    • 然而值得注意的是,如果您的用户上有外键,安全性将没有水合项目
    【解决方案3】:

    如何在twig中显示模仿者的示例:

    {% if is_granted('ROLE_PREVIOUS_ADMIN') %}
      {% for role in app.security.token.roles %}
        {% if role.role == 'ROLE_PREVIOUS_ADMIN' %}
          {{ role.source.user.username }}
        {% endif %}
      {% endfor %}
    {% endif %}
    

    【讨论】:

    • 你知道如何在 Symfony3 中做到这一点吗? app.security 变量已被弃用并删除,我正在寻找替代方案,因为我们正在更新到最新版本。
    • @FighterJet 使用 app.token_storage 而不是 app.security
    • app.token_storage 似乎不可用,根据docs...
    • "app.token_storage.token.roles" 这对我不起作用。我必须检查相同的条件 {% if role.role == 'ROLE_PREVIOUS_ADMIN' %} {{ role.source.user.username }} {% endif %} 请帮助我如何检查“ROLE_PREVIOUS_ADMIN”?
    • @mobize 从 Symfony 3.2 开始,app 变量具有 getToken() 方法,因此您可以通过 app.token (api.symfony.com/3.2/Symfony/Bridge/Twig/…) 从 twig 访问当前令牌。对于当前的 master 分支(4.2-DEV)仍然如此。
    【解决方案4】:

    如果您需要测试以前管理员用户的角色:

    使用 Symfony 3.4

    {% if is_granted('ROLE_PREVIOUS_ADMIN') %}
        {% for role in app.token.roles %}
            {% if role.role == 'ROLE_PREVIOUS_ADMIN' %}
                {% for role_from_previous in role.source.roles if role_from_previous.role == "ROLE_DELETE" %}
                    {{ role.source.user.username }} has "ROLE_DELETE"
                {% endfor %}
            {% endif %}
        {% endfor %}
    {% endif %}
    

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 2015-12-21
      • 2015-02-20
      • 2014-06-25
      • 2019-09-14
      • 2021-03-13
      • 2020-08-18
      • 2013-05-04
      相关资源
      最近更新 更多