how do i get the password eneterd via a costum user provider. I found this question:
Symfony Security / Custom User Provider : How to get the login password within the custom User Provider?
Which says i would have to overrise the loadUserByName method, and add the password as a parameter, the issue is that i cannot find the file he overrides:
security_listeners.xml
Where is this file located?
I found the:
$user = $this->userProvider->loadUserByUsername($username);
call in the DOAAuthenticationProvider, and i see that the method takes:
protected function retrieveUser($username, UsernamePasswordToken $token)
as augments, i asume i need to pass the password there, and then pass it to loadUserByName, which calls my costum userprovider method.
Any help on how to achieve this is appreciated.
You can create an AuthenticationHandler on your bundle. and the on successful login fetch the password from the token.
in services.yml:
security.authentication.success_handler:
class: Wix\UserBundle\EventListener\AuthenticationHandler
arguments: ["#security.http_utils", {}]
tags:
- { name: 'monolog.logger', channel: 'security' }
And sample class:
class AuthenticationHandler extends DefaultAuthenticationSuccessHandler
{
/**
* This is called when an interactive authentication attempt succeeds. This
* is called by authentication listeners inheriting from
* AbstractAuthenticationListener.
*
* #param Request $request
* #param TokenInterface $token
*
* #return Response never null
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$response = new RedirectResponse('/');
$response->setStatusCode(200);
return $response;
}
}
Related
How can I fetch the currently logged in User from anywhere within the Backend code? For example I have an EventSubscriber class and want to fetch it from there.
How can I do that w/o the help of i.e. AbstractController?
Symfony AbstractController is the core of most Controllers. Including EasyAdmin crud controller (XXXCrudController) extends AbstractController so you can access the same methods.
One of those is getUser() which return the current logged in user.
* Get a user from the Security Token Storage.
*
* #return UserInterface|null
*
* #throws \LogicException If SecurityBundle is not available
*
* #see TokenInterface::getUser()
*/
protected function getUser()
{
if (!$this->container->has('security.token_storage')) {
throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
}
if (null === $token = $this->container->get('security.token_storage')->getToken()) {
return null;
}
// #deprecated since 5.4, $user will always be a UserInterface instance
if (!\is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return null;
}
return $user;
}
So when trying to get the logged used in a controller, just use this method.
If you want to get the same thing, but for example in a service, you can basically do the same as what the method actually does by using the service injection with TokenStorageInterface to access the TokenStorage service which can get the current user.
So in your event subscriber, add TokenStorageInterface in your constructor to use it to first get the token and then your user. You may have to add another check to see if there is an user logged in (by checking if there is a token for example)
//YourService.php
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
private $tokenStorage
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function yourMethod()
{
//get token then user
$user = $tokenStorage->getToken()->getUser();
}
I'm implementing a GET request like below. This route allows anonymous access, but I want to give more sensitive information when the user is authenticated.
[Controller]
/*
* #Route ("/api/item/{code}.{_format}", name="api.item.get", defaults={"_format"="json"}})
* #Method("GET")
* #Secure(roles="ROLE_API, IS_AUTHENTICATED_ANONYMOUSLY")
*/
public function getItemAction(Request $request, $code)
{
/* #var UsernamePasswordToken $token */
$token = $this->get('security.token_storage')->getToken();
$user = $token->getUser();
// snip
}
[security.yml]
- { path: '^/?api/items/[a-zA-Z0-9-]+', role: [ROLE_API, IS_AUTHENTICATED_ANONYMOUSLY] }
I'm expecting the $user is a User object when the user is authenticated but it's a string type and the value is "anon.". What am I missing?
I can't try it since I don't have symfony 2.8 anymore (side note: you should seriously consider updating your version!) but have you tried something like this?
if ($user instanceof User) {
// fetch those sensitive info
}
I am trying to implement the LexikJwt package for my new API:
https://github.com/lexik/LexikJWTAuthenticationBundle
I just added my custom command to create a proper JWT token including my default roles for local testing. The next step would be to actually protect my routes. What i can't find however is exactly on how to do that. This is my current controller implementation using annotation routes
/**
* #Route(
* "/search",
* name="search",
* methods={"GET"},
* )
*/
class Search
{
/**
* #param AddressService $addressService
* #param Request $request
* #return JsonApiResponse
* #throws Exception
*/
public function __invoke(AddressService $addressService, Request $request)
{
$address = $addressService->createFromParams($request->query->all());
try {
$addressCollection = $addressService->search($address);
} catch (AddressNotFoundException $e) {
$addressCollection = [];
}
return new JsonApiResponse($addressCollection);
}
}
However the docs do not say anything about annotation routes and only on yml configs on security firewalls. The main thing i need is the token to be verified:
Is the token valid (matching the public key)
Is the token not expired
Does the route match the given roles
For example, i want the code above, which is an address service to match only if the token matches above and the token holds the role or scope: address:search.
Hope someone can help,
Pim
The issue was that the role should start with ROLE_. It is possible to override it though but this was the use case.
So, I've made an app with its own controller and entities. I've just installed the FOSUserBundle following the guide and I want to connect my app to the login, register, etc. I tried using the function 'path'. This is what looks like... 'href="{{path(menu.url)}}' ok, so I get an error: 'such route does not exist'. I decided to create another controller, this one called FosController, next to my previous one the DefaultController, I extended the FosController from SecurityController(login fosuserbundle) and decided to create with annotation a route called login and connect it to the parent method...
class FosController extends SecurityController
{
/**
* #Route("/hospitallogin", name="login")
* #Method({"GET", "POST"})
*
* #param Request $request
*
* #return Response
*/
public function login2Action(Request $request) {
parent::loginAction($request);
}
}
And I get this error:
The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?
I dont know what else to do, thanks for your time.
I decided to use this though it's not correct...
public function indexAction()
{
return $this->redirect('http://localhost:8000/login');
}
Using LexikJWTAuthenticationBundle, FOSRest, FOSUser how do I get authenticated user profile by token. Is it possible?
So let's say user is already authenticated via LexikJWT and I have an api endpoint like /api/profile where I send the token and I expect to get specified user data.
I'm using for frontend ReactJS with Redux.
This is an example of how to get your user by a service when the user is already authenticated:
class UserService
{
/** #var TokenStorageInterface */
private $tokenStorage;
/**
* #param TokenStorageInterface $storage
*/
public function __construct(
TokenStorageInterface $storage,
)
{
$this->tokenStorage = $storage;
}
public function getCurrentUser()
{
$token = $this->tokenStorage->getToken();
if ($token instanceof TokenInterface) {
/** #var User $user */
$user = $token->getUser();
return $user;
} else {
return null;
}
}
}
And in your services.yml:
tenant_user_service:
class: YourBundle\YourPackage\UserService
arguments: [ '#security.token_storage' ]
This will return your user - but be aware depending on the how user got set to the token during authentication this can be as well only your username as a string. But basically you get any content from your current $token->getUser().
i'm new but i can try...
you can use the annotation like
#Security("is_granted('ROLE_USER')")
in your controller and something like$this->getUser()->getUsername(); to get the username.
example:
$user = $this->get('doctrine.orm.default_entity_manager')
->getRepository('AppBundle:User')
->FindOne($this->getUser()->getUsername());`
after that you serialize datas, create new Response and return it.