GithubHelp home page GithubHelp logo

Comments (8)

gustvao avatar gustvao commented on August 11, 2024 3

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.

gustvao avatar gustvao commented on August 11, 2024 2

@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]

image

Can you pls point me to the correct direction? I believe I am missing something here.

Tks in advace

from oauth2-bundle.

X-Coder264 avatar X-Coder264 commented on August 11, 2024 1

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.

marvin-SL avatar marvin-SL commented on August 11, 2024

Thanks @gustvao, you really helped me

from oauth2-bundle.

mikemilano avatar mikemilano commented on August 11, 2024

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.

marvin-SL avatar marvin-SL commented on August 11, 2024

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.

mikemilano avatar mikemilano commented on August 11, 2024

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.

cnizzardini avatar cnizzardini commented on August 11, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.