Comments (8)
I managed to make it work, I was missing basically 2 things:
security.yaml
security:
encoders:
App\Domain\Model\Shop\Shop:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Domain\Model\Shop\Shop
property: username
# used to reload user from session & other features (e.g. switch_user)
and in my shoprepository, i needed to extend the ServiceEntityRepository
<?php
namespace App\Infrastructure\Repository;
use App\Domain\Model\Shop\Shop;
use App\Domain\Model\Shop\ShopRepositoryInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
/**
* Class ShopRepository
* @shop App\Infrastructure\Repository
*/
final class ShopRepository extends ServiceEntityRepository implements ShopRepositoryInterface {
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* ShopRepository constructor.
* @param EntityManagerInterface $entityManager
*/
public function __construct(
EntityManagerInterface $entityManager,
ManagerRegistry $registry) {
$this->entityManager = $entityManager;
parent::__construct($registry, Shop::class);
}
/**
* @param int $idShop
* @return Shop
*/
public function findById(int $idShop): ? Shop {
return $this->find($idShop);
}
/**
* @return array
*/
public function findAll() : array
{
return $this->findAll();
}
/**
* @param Shop $shop
*/
public function save(Shop $shop): void{
$this->entityManager->persist($shop);
$this->entityManager->flush();
}
/**
* @param Shop $shop
*/
public function delete(Shop $shop): void{
$this->entityManager->remove($shop);
$this->entityManager->flush();
}
}
hope this helps anyone that is struggling :)
from oauth2-bundle.
@X-Coder264 I am facing the same difficulties. I believe that a more explicit example with step by step in docs will help people further... I can offer to do a PR as soon as I manage to make it work.
Can you share some color with me please?
So I added the a few fields in my entity SHOP (that should be my user equivalent)
namespace App\Domain\Model\Shop;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Shop
*
* @ORM\Table(name="shop")
* @ORM\Entity(repositoryClass="App\Infrastructure\Repository\ShopRepository")
*/
class Shop implements UserInterface {
/**
* @var int
*
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
also added the mandatory mehtods, getRoles, getSalt, getUsername, getPassword and eraseCredentials.
I ran the migration and added a username called: [email protected]
After that I went ahead and put in my services.yaml
App\Application\Service\UserResolveListener:
# arguments:
# - '@app.ifrastructure.repository.shop_repository'
# - '@security.password_encoder'
tags:
- { name: kernel.event_listener, event: trikoder.oauth2.user_resolve, method: onUserResolve }
Had to comment the arguments part, otherwise I keep getting the error:
The service "App\Application\Service\UserResolveListener" has a dependency on a non-existent service "app.ifrastructure.repository.shop_repository".
Couldnt find a way to properly write that argument.. What should I put there? How do I do it? My ShopRepository is located in App\Infrastructure\Repository\ShopRepository.php
Ok, then I make a post to /token but the result is always the same, that it cannot find username [email protected]
Can you pls point me to the correct direction? I believe I am missing something here.
Tks in advace
from oauth2-bundle.
I've tried creating the
UserResolveListener
but it doesn't seem to be triggered but it's very likely that I'm not understanding how it is supposed to work.
The UserResolveListener
from the example listents to the UserResolveEvent
which is being dispatched here. This happens when you send a POST
request to the token endpoint (/token
) with the grant_type
being password
as can be seen in the test here. The job of the listener is to set the user (an implementation of Symfony\Component\Security\Core\User\UserInterface
) to the event (if valid username and password credentials were provided). Then our UserRepository
converts that user (if provided) to a League\OAuth2\Server\Entities\UserEntityInterface
implementation. If no user was set then the PasswordGrant
will just throw an invalid credentials exception here.
If you still have questions about how the password grant type is working feel free to ask.
from oauth2-bundle.
Thanks @gustvao, you really helped me
from oauth2-bundle.
Thanks @X-Coder264.. I have it working except for validating the password because of the issue @gustvao mentioned.
@gustvao How are you validating the password since the services can't be passed in as arguments in the service declaration?
from oauth2-bundle.
I didnt have issue with the service.
Here is service.yml (sorry I m on my phone)
app.user_provider:
class: App\Security\UserProvider
public: true;
app.repository.user_repository:
class: App\Repository\UserRepository
arguments:
- '@Symfony\Bridge\Doctrine\RegistryInterface'
- '@app.user_provider'
public: true;
App\EventListener\UserResolveListener:
arguments:
- '@app.user_provider'
- '@security.password_encoder'
- '@app.repository.user_repository'
tags:
- { name: kernel.event_listener, event: trikoder.oauth2.user_resolve, method: onUserResolve }
'
from oauth2-bundle.
Thank you @marvin-SL. I was still having trouble defining arguments, but it turns out autowiring worked for me.
services.yaml
App\EventListener\UserResolveListener:
tags:
- { name: kernel.event_listener, event: trikoder.oauth2.user_resolve, method: onUserResolve }
UserResolveListener.php
:
<?php
namespace App\EventListener;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Trikoder\Bundle\OAuth2Bundle\Event\UserResolveEvent;
final class UserResolveListener
{
/**
* @var UserProviderInterface
*/
private $userProvider;
/**
* @var UserPasswordEncoderInterface
*/
private $passwordEncoder;
/**
* UserResolveListener constructor.
* @param UserProviderInterface $userProvider
* @param UserPasswordEncoderInterface $passwordEncoder
*/
public function __construct(UserProviderInterface $userProvider, UserPasswordEncoderInterface $passwordEncoder)
{
$this->userProvider = $userProvider;
$this->passwordEncoder = $passwordEncoder;
}
...
from oauth2-bundle.
I actually got this working. The maintainers of this package REALLY REALLY REALLY need better documentation. IMO, a project is judged more on its documentation, than anything else... It should not take this long to figure out just a couple of lines of code. Our use-case was perhaps a bit different than others as we were getting this to work with a mongodb user provider.
For reference for MongoDb users, this is how our security.yaml is setup:
#security.yaml
security:
encoders:
App\Document\User:
algorithm: auto
providers:
mongo_provider:
mongodb:
class: App\Document\User
property: email
# ...
Now for services, see below for explanation.
# services.yaml
services:
App\EventListener\UserResolveListener:
# arguments:
# - '@security.user.provider.concrete.mongo_provider'
# - '@security.password_encoder'
tags:
- { name: kernel.event_listener, event: trikoder.oauth2.user_resolve, method: onUserResolve }
Moving to services.yaml, these settings mostly apply to everyone, except your UserRepository is likely Entity based unlike a Mongo one. I believe previous comments instruct how to set that up in services. For ours we used the factory option which builds args for you, this prevents you from attempting to hang yourself in a YAML file.
Take note on the first argument for App\EventListener\UserResolveListener, which is @security.user.provider.concrete.mongo_provider
. You shouldn't need these, since autowire should work, but if not I left in the args it would need. For the first arg you can see all the providers available to you by running:
docker-compose exec php bin/console debug:container user.provider
On my install, this outputs:
Select one of the following services to display its information:
[0] security.user.provider.missing
[1] security.user.provider.in_memory
[2] security.user.provider.in_memory.user
[3] security.user.provider.ldap
[4] security.user.provider.chain
[5] security.user.provider.concrete.mongo_provider
[6] doctrine.orm.security.user.provider
[7] doctrine_mongodb.odm.security.user.provider
This would be helpful to add to the documentation here: https://github.com/trikoder/oauth2-bundle/blob/v2.x/docs/password-grant-handling.md which didn't work for us because it needs a provider, that is a class which implements UserProviderInterface. Ultimately, those were autowired in so it was a bit of a waste of time.
So this works assuming you have a client such as this:
# php bin/console trikoder:oauth2:list-clients
------------ ---------- ------------- -------------- ------------
identifier secret scope redirect uri grant type
------------ ---------- ------------- -------------- ------------
clientId mysecret create,read password
------------ ---------- ------------- -------------- ------------
And you send an HTTP POST request to /token
with post body of following key-values:
client_id:clientId
client_secret:mysecret
grant_type:password
username:admin@localhost
password:password
from oauth2-bundle.
Related Issues (20)
- Symfony 5.3 new user interface support HOT 2
- Doctrine Bundle 2.4 support HOT 1
- How to get access token for all types of grants? HOT 3
- PHPDumper throws error on installation, string:OAUTH2_ENCRYPTION_KEY are never used
- How to override/extend Model-Classes for Client, AccessToken, etc
- Restricting routes by scope example HOT 1
- Symfony 5.3 Deprecation issue HOT 4
- in_memory persistence: provide client_id and client_secret from .env files HOT 1
- Writing the tests relying on config
- How can I get data from access token? HOT 2
- Symfony 5.3 Basic Setup, does not work! HOT 2
- [Question] How to manually generate a refresh token?
- Re-using unit test
- 1 package has known vulnerabilities HOT 1
- unexplained Client authentication failed error HOT 1
- Password Grant Flow
- Add Symfony 6 support HOT 2
- phpstan lvl 2 error on dev-master 09462b1 HOT 1
- sensio/framework-extra-bundle dependencya problem with 3.2.0 HOT 1
- is this project still maintained ? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from oauth2-bundle.