SecurityContext->isGranted() working in controller but not in service - symfony

I have a public area of my app accesible with no login or authentication, and when I run this code in a controller if ($securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) I get a true as expected.
Then I have a service defined like this:
main.services:
class: App\MainBundle\Services\MainServices
arguments: [ #doctrine.orm.entity_manager, #security.context, #service_container ]
But when I run this code:
public function __construct(EntityManager $em, SecurityContext $securityContext, Container $container) {
$this->em = $em;
$this->container = $container;
$this->securityContext = $securityContext;
error_log("MAIN");
if ($securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY'))
error_log("MAIN Anon");
else
error_log("MAIN no anon");
}
I get an exception:
Uncaught exception 'Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException' with message 'The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.'
The service is invoked right after the first command in controller.
Thank you

This error could occur when service initializes before security token created. Try not to check access in constructor, move this check to method, called from your controller.

Use it only if a token is defined and #Ziumin is wright.
public function __construct(EntityManager $em, SecurityContext $securityContext, Container $container) {
$this->em = $em;
$this->container = $container;
$this->securityContext = $securityContext;
error_log("MAIN");
$token = $this->securityContext->getToken();
if (is_object($token)) {
if ($securityContext->isGranted('IS_AUTHENTICATED_ANONYMOUSLY'))
error_log("MAIN Anon");
else
error_log("MAIN no anon");
}
}

Related

Symfony Event Listener, Debug bar doesn't work

I have this EventListener class who update the user activity in database:
App\EventListener\ControllerListener:
tags:
- { name: kernel.event_listener, event: kernel.controller }
<?php
namespace App\EventListener;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\Security\Core\Security;
class ControllerListener
{
private $security;
private $em;
public function __construct(Security $security, EntityManagerInterface $entityManager)
{
$this->security = $security;
$this->em = $entityManager;
}
public function onKernelController(ControllerEvent $event)
{
$user = $this->security->getUser();
$em = $this->em;
if ($user) {
$user->setLastSeenDate(new \DateTime());
$em->persist($user);
$em->flush();
}
}
}
The query is OK and update the user inside the database, but the debug bar is broken after that:
An error occurred while loading the web debug toolbar
If I remove the query inside ControllerListener class, the debug bar work again.
How to fix this issue please?
Solved with a dependency update:
composer update
php bin/console cache:warmup

Symfony Worker - Consume Messages - EntityManager

I use Symfony 4 with messenger and I use a worker who consumes my messages as a long-running process.
I have a bug with doctrine if I delete my post and recreate a new one and I dispatch my message. $post have the old data and not the new one.
I have tried a lot of things and nothing work, it works when I restart my worker.
class ChannelMessageHandler implements MessageHandlerInterface
{
private $channel;
private $bus;
public function __construct(ChannelService $channel, MessageBusInterface $commandBus)
{
$this->channel = $channel;
$this->bus = $commandBus;
}
public function __invoke(ChannelMessage $channelMessage)
{
$error = $this->channel->handleChannel($channelMessage->getUser(), $channelMessage->getService());
if ($error) {
throw new Exception($error[0]);
}
$this->bus->dispatch(new FeedMessage($channelMessage->getUser(), $channelMessage->getService()));
}
}
}
My MessageHandler call a service :
class ChannelService implements ContainerAwareInterface
{
use ContainerTrait;
protected $em;
protected $logger;
public function __construct(EntityManagerInterface $entityManager, LoggerInterface $logger)
{
$this->em = $entityManager;
$this->logger = $logger;
}
public function handleChannel($userId, $serviceName)
{
$user = $this->em->getRepository('App:User\Authentication\User')->findOneById($userId);
$post = $user->getPost();
return $this->getUserAnalyticBy($post, $serviceName);
}
thanks a lot

Symfony 2 Injecting logger service

I got a strange problem using the logger service in symfony 2:
When injecting the logger to a service, I get a type error because LoggerInterface expected but Symfony\Bridge\Monolog\Logger given.
Also if I try to inject a custom logger, I get error because of undefined service.
Here is my code:
confiy.yml
monolog:
channels: ['payment']
handlers:
paymentlog:
type: stream
path: "%kernel.logs_dir%/payment.log"
level: debug
channels: [payment]
service.yml
#payment_services
payment.gateway_payments:
class: AppBundle\Service\paymentService
arguments: ["#service_container", "#doctrine.orm.entity_manager", "#logger"]
Service:
<?php
namespace AppBundle\Service;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
class paymentService {
private $container;
private $em;
private $logger;
public function __construct(ContainerInterface $container, EntityManager $em, LoggerInterface $logger){
$this->container = $container;
$this->em = $em;
$this->logger = $logger;
}
Also injecting the logger with #monolog.logger.paymentlog is giving me an error "undefinded service"
Can someone please tell me where I am wrong?
THX a lot.
try this:
use Monolog\Logger;
instead of this:
use Symfony\Component\HttpKernel\Log\LoggerInterface;
And after this;
public function __construct(ContainerInterface $container, EntityManager $em, Logger $logger){
insetad of this:
public function __construct(ContainerInterface $container, EntityManager $em, LoggerInterface $logger){

Symfony 2.6 get Service LoggedUser Catchable Fatal Error: Argument 3 must be an instance

I want to implement the security.token_storage as a service to get the user that is logged in; so when the user writes a post or a comment the field "Author" is automatically set.
I cannot get it working:
Attempted to call method "get" on class "Blog\BlogBundle\Services\PostManager".
How can I implement it as a service and use it?
The UserManager (as a service):
namespace Usuarios\UsersBundle\Services;
class UserManager
public function getloggedUser()
{
$loggedUser = $this->get('security.token_storage')->getToken()->getUser();
return $loggedUser;
}
The service.yml for the UserManager config:
services:
user_manager:
class: %user_manager.class%
arguments:
- #doctrine.orm.entity_manager
The PostManager, that uses the getloggedUser function:
namespace Blog\BlogBundle\Services;
class PostManager
private $em;
private $formFactory;
private $um;
/**
* #param EntityManager $em
* #param formFactoryInterface $formFactory
* #param UserManager $um
*/
public function __construct(EntityManager $em, FormFactoryInterface $formFactory, UserManager $um)
{
$this->em = $em;
$this->formFactory = $formFactory;
$this->um = $um;
public function createComment (Post $post, Request $request)
{
$comment = new Comment();
$comment->setPost($post);
//this is the line failing:
$comment->setAuthorName($this->um->getloggedUser());
$form = $this->formFactory->create(new CommentType(), $comment);
$form->handleRequest($request);
if ($form->isValid()) {
$this->em->persist($comment);
$this->em->flush();
return true;
}
return $form;
Note "user_manager" is defined as a service and is fully functional since other functions using it are working. Why cannot I call the UserManager service from the PostManager service? The error I get is:
Catchable Fatal Error: Argument 3 passed to Blog\BlogBundle\Services\PostManager::__construct() must be an instance of Usuarios\UsersBundle\Services\UserManager, none given, called in C:\xampp\htdocs\eScribely2\app\cache\dev\appDevDebugProjectContainer.php on line 2535 and defined
services do not have the get convenience method that controllers do. You need to pass the container in as an argument when you build the service and store it as a member variable and then call you service.
$this->container->get('user_manager');
Optionally you can just pass in your user manger and not have to use the container at all.

Symfony Service Configurator: getToken with security.context is NULL

I'm using Symfony Service Configurator in my project to configure a service after its instantiation (Docs),
in Configure method I need the current user logged so I inject the container and I tried to get the token form Security.context service but I got always NULL.
I tried also to inject only Security.context in my Configurator construct but I got same result.
Any ideas pls
Thanks.
class MyConfigurator
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function configure()
{
$user = $this->container->get('security.context')->getToken();
var_dump($user); // = NULL
}
}
I resolve the problem by getting the UserId from the session and fetch the current User from Database.
The UserId is set previously by a AuthenticationListener in my project.
So I modify my Configurator construct to be like this:
/**
* #param EntityManager $em
* #param Session $session
*/
public function __construct(EntityManager $em, Session $session)
{
$this->em = $em;
$this->session = $session;
}
A better way should be:
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class MyConfigurator
{
private $tokenStorage;
public function __construct(EntityManager $em, TokenStorage $tokenStorage)
{
$this->em = $em;
$this->tokenStorage= $tokenStorage;
}
public function configure()
{
$user = $this->tokenStorage->getToken()->getUser();
}
....

Resources