问题
Whilst looking around at using AuthenticationHandlers I saw that Symfony supports EventSubscribers which can be more flexible when authenticating with multiple methods.
I have been using this as an example: https://knpuniversity.com/screencast/guard/success-handling
So I have got my subscriber class all setup, but what I do not know how to do is register is as an event in Silex.
I am pretty sure that I need to use the $app['dispatcher']
but what I do not know is what event to listen on. Using the example from the page, in a Symfony configuration, the servics is tagged with kernel.event_subscriber
but when I did the following in Silex nothing happened:
$app['dispatcher'] -> addListener(KernelEvents::EVENT_SUBSCRIBER, function(Event $event) use ($app) {
... do something ...
});
I am pretty sure that the event I listening on is wrong, but I did not get any errors either. Is this sort of thing possible in Silex?
thanks, Russell
Update:
This is my subscriber class:
<?php
namespace MySubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class ApiKeySubscriber implements EventSubscriberInterface {
public function onInteractiveLogin(InteractiveLoginEvent $event) {
file_put_contents("/tmp/onInteractiveLogin.txt", "It was ehere");
}
public static function getSubscribedEvents() {
return array(SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin');
}
}
The firewall is very simple:
// Configure the firewalls for the application
$app['security.firewalls'] = array(
'basicauth' => array(
'pattern' => '^/auth',
'http' => true,
'users' => $app -> share(function() use ($app) {
return new UserAccount($app);
})
)
);
And then I add the subscriber with:
$app['dispatcher'] -> addSubscriber(new \MySubscriber\ApiKeySubscriber());
I assume that Basic Auth qualifies as interactive login, so I am not sure why the method is not being called.
回答1:
Your subscriber class should implement EventSubscriberInterface
. If it does, just use the addSubscriber
method instead of addListener
.
$app['dispatcher']->addSubscriber(new MyEventSubscriber());
Your event subscriber has a method called getSubscribedEvents
that tells Symfony what events to subscribe to so you don't need to pass an event name at all. See the Symfony docs for more information.
Update (security listener):
The basic HTTP authentication method is not considered interactive login. That is for a typical web based login form.
You may be able to use AuthenticationEvents::AUTHENTICATION_SUCCESS
instead. Your listener method will receive an AuthenticationEvent
instance.
<?php
namespace MySubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
class ApiKeySubscriber implements EventSubscriberInterface
{
public function onAuthenticate(AuthenticationEvent $event)
{
file_put_contents("/tmp/onInteractiveLogin.txt", "It was here");
}
public static function getSubscribedEvents()
{
return array(AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthenticate');
}
}
来源:https://stackoverflow.com/questions/32827385/is-it-possible-to-use-eventsubscribers-with-silex