[英]Symfony 3 authenticating against pages under firewall
我遇到的問題是我試圖將用戶自動登錄到我的網站的個人資料部分,但是由於它受到symfony防火牆的保護,因此在自動登錄系統啟動之前,用戶已重定向到登錄頁面。
因此,我想知道當用戶嘗試訪問防火牆下的頁面時是否觸發了一個事件,我可以聽該事件,或者最終可以使用另一種機制來解決此情況。
目前,我要解決的問題是創建一個自定義重定向控制器,該控制器將我的用戶發送給autologin哈希,並包含一個路徑參數,該參數包含將用戶發送到的最終位置,因此,在對他們進行身份驗證之后,我會將其重定向到最終目的地。
我要實現的目標是能夠直接將用戶自動登錄到防火牆后面的那些頁面,而無需使用自定義控制器來自動登錄用戶,然后將他們重定向到所需的頁面。
謝謝。
D.
基本上,您有三個選擇:
如果您想真正收聽防火牆,則需要創建一個自定義身份驗證提供程序 ,這是一項艱巨的任務。
您可以在文檔中遵循此指南: http : //symfony.com/doc/current/security/custom_authentication_provider.html或http://sirprize.me/scribble/under-the-hood-of-symfony-security/
這里的重點是創建您自己的防火牆偵聽器 ,該偵聽器決定是否對用戶進行身份驗證。 防火牆可以有多個偵聽器。
或者,您可以偵聽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']
(由於您想進行身份驗證而不是授權用戶,因此可能不是您的解決方案,但我還是為其他人提及。)
在app / config / security.yml中 , 更改訪問控制設置,以便所有人都可以訪問安全區域:
# ...
access_control:
- { path: ^/secured-area$, role: IS_AUTHENTICATED_ANONYMOUSLY }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.