Symfony 2:两步(非双因素)身份验证

时间:2014-04-29 19:38:50

标签: symfony authentication authorization symfony-2.3

我需要在Symfony 2.3中实现两步(而不是双因素)身份验证。第一步是通常的用户+密码+ csrf表单。第二步是"条款&条件",用户在首次登录或更新条款时应该看到,并且他们必须勾选一个框以便继续访问网站的其余部分。

第二步并非真正的认证步骤,但除非第二步被采取行动,否则用户不应该能够访问网站的其余部分,因此从概念上考虑它是有意义的作为身份验证的一部分。

在写这篇文章时,橡皮鸭告诉我,我应该考虑授权,并且启动用户的想法还没有接受条款"角色,并将角色更新为完全授权的用户"如果条款已被接受。这听起来像是迄今为止最完美的解决方案,因为我可以让防火墙处理逻辑。

到目前为止偶然发现了这些信息:
http://blogsh.de/2011/11/15/change-user-roles-during-a-session-in-symfony/
http://php-and-symfony.matthiasnoback.nl/2012/07/symfony2-security-creating-dynamic-roles-using-roleinterface/

当我深入研究这个问题时,我希望会遇到一种行为:防火墙会显示错误,而不是将用户重定向到“条款”页面,然后在他们接受后让他们继续前进

以前是否有人这样做过,所以我必须发明尽可能少的车轮?

2 个答案:

答案 0 :(得分:1)

我找到了一个有类似问题的人,他收到了我可以使用的解决方案:

Symfony 2 : Redirect a user to a page if he has a specific role

事件监听器类:

namespace Acme\DemoBundle\Lib;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\HttpKernel;

use Acme\DemoBundle\Entity\User;

class TermsAndConditionsRequestListener
{
    private $security;
    private $router;

    public function __construct($security, $router)
    {
        $this->security = $security;
        $this->router = $router;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        /* http://symfony.com/doc/2.3/cookbook/service_container/event_listener.html */
        if (HttpKernel::MASTER_REQUEST !== $event->getRequestType())
        {
            // don't do anything if it's not the master request
            return;
        }

        $request = $event->getRequest();
        $route = $request->attributes->get('_route');

        if ($route === '_wdt' || substr_compare($route, '_profiler', 0, 9) === 0)
        {
            // ignore development routes
            return;
        }

        if (in_array($route, array('terms_and_conditions_force', 'terms_and_conditions_accept')))
        {
            // don't redirect into an infinite loop
            return;
        }

        $token = $this->security->getToken();
        $user = $token ? $token->getUser() : null;
        $user_role = ($user instanceof User) ? $user->getRole() : null;

        if ($user_role === 'ROLE_USER' && (is_null($user->getTermsAcceptedDate()) || $terms_are_newer_than_acceptance_date))
        {
            $url = $this->router->generate('terms_and_conditions_force');
            $event->setResponse(new RedirectResponse($url));
        }
    }
}

事件监听器服务:

acme.wvml.event_listener.request.terms_and_conditions:
    class: Acme\DemoBundle\Lib\TermsAndConditionsRequestListener
    arguments: [@security.context, @router]
    tags:
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

答案 1 :(得分:0)

您必须扩展symfony UserAuthenticationProvider。您可能希望在checkAuthentication函数中添加检查,如果失败则返回有关条款和条件的错误消息。