【问题标题】:Symfony 3 authenticating against pages under firewallSymfony 3 对防火墙下的页面进行身份验证
【发布时间】:2016-11-15 09:10:49
【问题描述】:

我遇到的问题是我试图让用户自动登录到我网站的个人资料部分,但由于它受到 symfony 防火墙的保护,因此在自动登录系统启动之前,用户会被重定向到登录页面。

所以我想知道当用户尝试访问防火墙下的页面时是否会触发一个事件,我可以收听该事件,或者最终我可以使用另一种机制来解决这种情况。

目前我采取的解决方法是创建一个自定义重定向控制器,我将用户发送到该控制器,并使用自动登录哈希和包含最终位置的路径参数将用户发送到,因此在验证他们之后我将他们重定向到最终目的地。

我想要实现的目标是能够让用户直接自动登录到防火墙后面的那些页面,而无需使用自动登录用户然后将他们重定向到所需页面的自定义控制器。

谢谢。

D.

【问题讨论】:

  • 是或否,取决于您想要实现的目标,而您根本没有描述...
  • 编辑,我想实现的目标:) @martin

标签: php authentication symfony autologin


【解决方案1】:

基本上,您有三个选择:

1。创建自定义身份验证提供程序

如果你想真正监听防火墙,你需要创建一个自定义的身份验证提供程序,这是一项相当具有挑战性的任务。

您可以按照文档中的指南进行操作:http://symfony.com/doc/current/security/custom_authentication_provider.htmlhttp://sirprize.me/scribble/under-the-hood-of-symfony-security/

这里的重点是创建您自己的防火墙监听器,它决定是否对用户进行身份验证。一个防火墙可以有多个监听器。

2。倾听每个请求

或者,您可以监听kernel.request 事件,可能手动检查您是否在安全路径上,如果是,则通过辅助方法手动验证用户。示例:

namespace AppBundle\Subscriber;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;

class RequestSubscriber implements EventSubscriberInterface
{

private $tokenStorage;

private $eventDispatcher;

public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher)
{
    $this->tokenStorage = $tokenStorage;
    $this->eventDispatcher = $eventDispatcher;
}

public static function getSubscribedEvents()
{
    return [ KernelEvents::REQUEST => 'onRequest' ];
}

public function onRequest(GetResponseEvent $event)
{
    // only master requests and not authenticated users
    if (!$event->isMasterRequest() || $this->isUserLoggedIn()) {
        return;
    }

    // add your own logic for creating or loading a User object
    // and filtering secured routes
    /* ... */

    // wohoo, user is going to be logged in manually!
    $this->authenticate($user, $event->getRequest(), 'secured_area');
}

protected function authenticate(UserInterface $user, Request $request, String $provider) : Bool
{
    // password doesn't matter in this case
    $token = new UsernamePasswordToken($user, null, $provider, $user->getRoles());

    // actual authenticating
    $this->tokenStorage->setToken($token);

    // dispatch the authentication event, so event listeners can do stuff
    $loggedUser = $token->getUser();
    if ($loggedUser instanceof UserInterface && $loggedUser->isAccountNonLocked() &&
        $loggedUser->isEnabled()) {

        $this->eventDispatcher
            ->dispatch(
                SecurityEvents::INTERACTIVE_LOGIN,
                new InteractiveLoginEvent($request, $token)
            );

        return true;

    }

    return false;
}

protected function isUserLoggedIn()
{
    $token = $this->tokenStorage->getToken();

    if (!$token) {
        return false;
    }

    return ($token->getUser() instanceof UserInterface);
}
}

别忘了将其添加到 app/config/services.yml

app.request_subscriber:
  class: AppBundle\Subscriber\RequestSubscriber
  tags:
    - { name: kernel.event_subscriber }
  arguments: ['@security.token_storage', '@event_dispatcher']

3。关闭授权

(可能对你来说不是一个解决方案,因为你想验证,而不是授权用户,但我仍然为其他人提。)

app/config/security.yml中,更改访问控制设置,让每个人都可以访问安全区域:

# ...
access_control:
  - { path: ^/secured-area$, role: IS_AUTHENTICATED_ANONYMOUSLY }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2015-08-03
    • 2013-07-04
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多